Stm32 USB virtual com port example

Gast #1401854
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
Gast #1402124
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
Gast #1403509
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
Gast #1410530
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
#1411030
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
Gast #1417145
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
Gast #1417284
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
Gast #1417286
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?
Gast #1417536
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.
Gast #1417570
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
Gast #1417937
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???
Gast #1418030
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
Gast #1418517
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
Gast #1418599
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??
Gast #1418685
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
#1419334
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
#1722938
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
#1725387
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren