Hallo zusammen,
Ich suche schon die ganze Zeit nach einer Softwareimplementierung von
USB Funktionalitäten für STM32 Controller. Für die AVR Familie gibt es
ja zum Beispiel die V-USB Variante. Gibt es auch soetwas ähnliches für
die STM32? Ich habe schon mehrere Stunden Google geqüalt aber nicht
wirklich etwas gefunden.
Gruß,
Nick
USBLover schrieb:> Hallo zusammen,>> Ich suche schon die ganze Zeit nach einer Softwareimplementierung von> USB Funktionalitäten für STM32 Controller. Für die AVR Familie gibt es> ja zum Beispiel die V-USB Variante. Gibt es auch soetwas ähnliches für> die STM32? Ich habe schon mehrere Stunden Google geqüalt aber nicht> wirklich etwas gefunden.>> Gruß,> Nick
Warum nimmst du keinen STM32 mit HW-USB? Der Grund wird sein, dass
niemand extra einen ST32 ohne USB kauft um dann USB per Software
reinzufrickeln.
Klar das wäre das einfachste, habe aber noch fast 20 STM32F030C8T6 hier
rumliegen, und bei dem ein oder anderen Projekt währe eine USB Funktion
ganz nett. Versuche also einfach ein wenig Geld zu sparen.
USBLover schrieb:> Klar das wäre das einfachste, habe aber noch fast 20 STM32F030C8T6 hier> rumliegen, und bei dem ein oder anderen Projekt währe eine USB Funktion> ganz nett. Versuche also einfach ein wenig Geld zu sparen.
38,20 EUR kosten die beim hbe-shop. Und dafür willst du dir Stundenlang
eine SW-USB Lösung ans Bein binden? Absoluter Unsinn. Nimm die
vorhandenen STM für andere Projekte und kauf z.B. STM32F04x für die USB
Geschichten.
Zum Basteln und da es ja Hobby ist, hätte ich da jetzt kein großes
Problem mit gehabt. Aber du hast wahrscheinlich recht, gleich einen mit
USB Support zu nehmen macht es schneller und wahrscheinlich auch
wesentlich stabiler läuffähig.
Bei richtiger Implementierung muss sich eine Software Implementierung
nicht vor der Hardware Version verstecken. Der Grund dass es Software
USB eigentlich nur für avrs gibt ist jedoch, dass man für die
Implementierung ein sehr genaues Timing braucht und dieses bei vielen
Mikrocontrollern nur sehr schwer bis gar nicht geht. Sobald man
Prefetch, caches oder irgendwelche andere Sachen in Controllern findet,
welche die Laufzeit nichtdeterministisch machen, ist es praktisch
nicht/kaum mehr möglich das Timing einzuhalten.
Na das wäre doch mal eine nette Assemblerübung.
Wir haben beim F030 USB-konforme 48MHz und sehr schicke Peripherie plus
NVIC und DMA.
Damit sollte die Implementation deutlich einfacher sein, als auf einem
AVR.
Benötigt wird noch ein signierter CDC-Treiber, z.B. für Win7.
Marcus H. schrieb:> Na das wäre doch mal eine nette Assemblerübung.> Wir haben beim F030 USB-konforme 48MHz und sehr schicke Peripherie plus> NVIC und DMA.>> Damit sollte die Implementation deutlich einfacher sein, als auf einem> AVR.
Eben nicht. Die Laufzeit ist beim Stm32f0 eben nicht vorhersehbar wie
beim avr. Dma könnte das Ganze noch schwieriger machen, wenn es die CPU
blockieren kann (keine Ahnung wo hier die Prioritäten liegen).
> Benötigt wird noch ein signierter CDC-Treiber, z.B. für Win7.
Cdc kann man gleich vergessen. Dafür benötigt man bulk-endpoints und
diese gibt es erst ab full-speed (12MBit/s). Das schafft man Software
erst im dreistelligen MHz-Bereich. Bulk-endpoints mit low-speed scheinen
zwar teilweise zu funktionieren, aber es ist klar gegen die
Spezifikation und damit Pfusch. Für cdc reicht übrigens ein .inf-file.
Den Treiber bringt Windows selbst mit.
Mit einem Oszi wirst du nicht weit kommmen. Es geht beim Debuggen von
USB eigentlich nie um den physischen Teil, sondern um die Daten. Man
muss schauen, ob die Pakete richtig übertragen werden und ob deren
Inhalt stimmt. Dafür braucht man eher einen Logikanalyser mit
USB-Decoder. Es ist auch wichtig, dass der Controller zur richtigen Zeit
sendet. Bei USB kommt noch erschwerend hinzu, dass die Leitungen
bidirektional sind, d.h. man kann nicht einfach feststellen ob gerade
der Host oder das Device sendet. Oftmals muss man einen Großteil der
Kommunikation mitschneiden. Mit einem Speicheroszi kann man das machen,
aber dann die ganzen Bits von Hand zu dekodieren ist, sagen wir mal,
mühsam. Und für eine vollständige Enumeration werden ziemlich viele
Pakete und noch mehr Bits ausgetauscht. Und wenn diese fehlschlägt, dann
sagt Windows einfach USB-Gerät funktioniert nicht.
Im Reference Manual findest du auf Seite 56 einen kurzen Absatz darüber
wie der Controller liest. Glücklicherweise hat der Controller noch keine
Sprungvorhersage. Allerdings ist Prefetch schon ärgerlich genug wenn man
ein präzises Timing braucht. Und sobald man mit DMA auf den Flash
zugreift, ist es schon nicht mehr berechenbar. Evtl. sieht es mit
Ram-Ausführung besser aus, aber dort könnte es auch wieder Fallstricke
geben. VUSB synchronisiert den µC im Interrupt als Erstes, und ist damit
maximal ein Takt daneben (+-166ns). Ich denke schon, dass man es ARMs
schaffen kann. Aber einfacher wird es definitiv nicht. Und die
Dokumentation, besonders wenn es um präzises Timing geht ist lausig bis
nicht vorhanden.
Du kannst es ja gerne versuchen, aber vielleicht schaust du dir vorher
mal die USB-Spezifikationen an (knapp 1000 Seiten), damit du eine
Vorstellung von dem Aufbau von USB bekommst. USB in a Nutshell ist auch
recht geeignet um einen Überblick darüber zu bekommen. Mit der
Spezifikation schafft man übrigens höchstens die Enumeration. Für ein
richtiges USB-Gerät braucht man dann noch die Spezifikationen der
verwendeten USB-Class, was in der Regel nochmal ein paar hundert bis
tausend Seiten sind (je nach Komplexität der Klasse (HID/CDC/Massstorage
ist eher einfach).
Ok, ok - Du hast mich davon überzeugt, dass Du Dir die Aufgabe nicht
zutraust.
Die Frage ob aber jemand anderes, insbesondere mit der Codevorlage von
VUSB, das umsetzen kann, ist noch offen.
Ich für meinen Teil habe seit dem Einstieg in die STM32-Familie kein
einziges CPLD/FPGA mehr gebraucht, um Timing bis ca. 50MHz umzusetzen.
Vor MAHPONG war es auch nicht so selbstverständlich, BAS-Video mit einem
8MHZ AVR Controller zu basteln. Das war damals auch eine Fingerübung im
Weihnachtsurlaub. Und ich habe seitdem noch mächtig geübt. Aus heutiger
Sicht sieht der Code für mich fürchterlich aus. ;)
Cyblord -. schrieb:> auf z.B. STM32F04x für die USB Geschichten.
#Kanonen #Spatzen
Der STM32F051 kann USB und ist fast identisch zu dem jetzt benutzten
f030.
Guest schrieb:> Cyblord -. schrieb:>> auf z.B. STM32F04x für die USB Geschichten.>> #Kanonen #Spatzen>> Der STM32F051 kann USB und ist fast identisch zu dem jetzt benutzten> f030.
Warum ist jetzt der F05 ok, aber F04 Kanonen auf Spatzen?
Ich empfahl KEINEN STM32F4! Wusste nur aus dem Stehgreif nicht mehr ob
nur die F04 oder F05 Reihe USB an Bord haben. Die F0 Reihe hat das eher
sporadisch.
Cyblord -. schrieb:> Ich empfahl KEINEN STM32F4!
ok, davon bin ich ausgegangen, denn einen anderen ohne USB vorzuschlagen
währe noch Sinnloser als einen 'Riesen' (F4xx) der wenigstens USB kann.
USB können die F05x und F07x.
Marcus H. schrieb:> Ok, ok - Du hast mich davon überzeugt, dass Du Dir die Aufgabe nicht> zutraust.>> Die Frage ob aber jemand anderes, insbesondere mit der Codevorlage von> VUSB, das umsetzen kann, ist noch offen.>> Ich für meinen Teil habe seit dem Einstieg in die STM32-Familie kein> einziges CPLD/FPGA mehr gebraucht, um Timing bis ca. 50MHz umzusetzen.
Mit Timern kein Problem. Aber mit Assemblercode Timing zu erzeugen,
welches welches +-250ns genau ist, ist was anderes. Vor allem wenn man
nicht einmal weiß, wie lange manche Assemblerbefehle gehen! Denn je nach
internem Aufbau macht dir Prefetch, Cache oder DMA deinen Befehl einfach
länger. Vielleicht geht es so ähnlich wie bei VUSB, wenn man den Core
stark einschränkt und das Zeugs deaktiviert. Aber um das herauszufinden,
müsste man erst mal eine Menge Assemblertests machen, weil vieles
einfach nicht dokumentiert ist und hoffen, dass das auch bei neueren µCs
so bleibt. Für die Controller müsste man mMn eigentlich einen anderen
Ansatz wählen. Ich würde mir so ein Forschungsprojekt durchaus zutrauen
- auch wenn nicht einmal klar ist, ob das Ziel erreichbar ist. Aber es
kostet einfach eine Menge Zeit. Und bei deinem Hintergrundwissen wird
das unter einem Jahr mit Sicherheit nichts. Aber du glaubst über mich
urteilen zu können.
avr schrieb:> Und bei deinem Hintergrundwissen wird> das unter einem Jahr mit Sicherheit nichts. Aber du glaubst über mich> urteilen zu können.
Tatsächlich habe ich mir eine Meinung über Dich gebildet.
Mein Hintergrundwissen im Rechnen erlaubt mir abzuschätzen, dass 250ns
bei 48MHz 12 Taktzyklen entspricht. Da ist viel Luft für Jitter jeder
Art.
Eine Grundlagenrecherche und Durchsicht des VUSB-Codes hat mich zu
meiner ersten Aussage geführt - dass das eine "Fingerübung" ist.
Ich würde für die von Dir erwähnte Studie eine Woche inkl. Debugging
veranschlagen.
Mein erster Kontakt mit USB war ein in Maschinensprache programmierter
Intel 80930Ax. Das war zu einem Zeitpunkt, als die c't noch vom "Useless
Serial Bus" geschrieben hat.
Für die Entwicklung musste man extra Win98 installieren.
http://cpushack.com/IntelMicrocontrollers.html
Marcus H. schrieb:> Mein Hintergrundwissen im Rechnen erlaubt mir abzuschätzen, dass 250ns> bei 48MHz 12 Taktzyklen entspricht. Da ist viel Luft für Jitter jeder> Art.
Anscheinend nicht. Denn der Jitter ist völlig egal, solange er bei 250ns
bleibt. Wenn er sich jedoch akkumuliert, dann bist du ganz schnell
außerhalb dieses Rasters.
Marcus H. schrieb:> Ich würde für die von Dir erwähnte Studie eine Woche inkl. Debugging> veranschlagen.
Dann darfst du das gerne machen und die Ergebnisse teilen. Die Studie
wird das kleinste des Gesamtprojektes sein.
Und ich sage es nocheinmal: Wenn du den VUSB-Code portieren willst, dann
musst du zuerst den Controller dazu bringen, dass jeder Befehl eine
deterministische Laufzeit hat. Als kleiner Tipp: Bei 48 MHz mit
Prefetch, hat sogar Quell- und Zieladresse bei einem Sprung eine
Auswirkung auf die Ausführungsdauer. Das könnte man sich sparen, wenn
man den Controller mit 24 MHz laufen lässt. Blöderweise sind die ganzen
Bitoperationen auf Ports auf dem Cortex M0 relativ langsam. Für ein
einfaches "sbic" auf dem AVR braucht man bei ihm mindestens 4 mal so
lange. Und jeder Portzugriff dauert doppelt so lange.
Aber probiere es doch aus. Spätestens beim Debugging wirst du mit diesem
Ansatz scheitern. Denn so etwas funktioniert nie auf Anhieb.
Avr, ich ziehe mich jetzt aus diesem Austausch zurück. Jedem der sich in
das Thema reinarbeiten möchte, sei nochmal die bereits genannte
STM32F0-Doku ans Herz gelegt:
PM0215
RM0091
avr schrieb:> Blöderweise sind die ganzen> Bitoperationen auf Ports auf dem Cortex M0 relativ langsam.
Warum sollten sie denn langsam sein? Wenn man das Zauberwort "BSRR"
gefunden hat, dann hat man nicht mehr die Arie "laden, logische
Operation, zurückschreiben".
Nop schrieb:> Wenn man das Zauberwort "BSRR" gefunden hat, dann hat man nicht mehr die> Arie "laden, logische Operation, zurückschreiben".
Du hast keine Ahnung von dem Befehl sbic, aber einfach mal voll aus dem
Zusammenhang zitiert. Mit deinem tollen Register kannst du die Operation
auch gar nicht abbilden.
Beim avr kann man zusätzlich übrigens in einem Takt auf die Ports
zugreifen. Selbst dein bsrr ist Faktor 2 langsamer (beim M0).
Aber Hauptsache ohne Ahnung gepöbelt. Scheint hier irgendwie Normalität
zu werden.
Da gibt es IMHO ganz andere lustige Probleme:
Der von ST gelieferte STM32F4 USB Referenz Code (Examples) ist gnadenlos
mit Bugs gespickt. Die HAL ebenso. Teilweise werden wichtige Flags nicht
gesetzt bzw. gelöscht.
Es führt IMHO kein Weg daran vorbei, die Treiber selbst zu
implementieren (sofern man es mit gutem Gewissen an Kunden
weiterverschachern möchte).
Der Einzige, der hier rumpöbelt, bist Du. Sei's drum, solange Du
wenigstens was Fachlich interessantes dabei rüberbringst, sind Deine
sozialen Defizite mir egal.
Portzugriffe auf STM32 brauchen übrigens nur bedingt zwei Takte -
nämlich wenn man sie "back to back" ausführt. Dann stalled er. Macht man
dagegen dazwischen noch andere Befehle, dann ist das effektiv ein Takt.
Daß sich sbic 1:1 auf STM32 abbilden läßt, habe ich übrigens auch nicht
behauptet. Aber auch Deine Defizite im Lesen seien Dir nachgesehen. Daß
STM32 als load/store-Architektur das nicht kann, ist ja wohl klar.
Dennoch sehe ich in der Praxis, daß Leute auf STM32 trotz BSRR immer
noch mit load-modify-write arbeiten, so daß der Hinweis alles andere als
offtopic war.
Nop schrieb:> Der Einzige, der hier rumpöbelt, bist Du. Sei's drum, solange Du> wenigstens was Fachlich interessantes dabei rüberbringst, sind Deine> sozialen Defizite mir egal.
Wer im Glashaus sitzt...
> Portzugriffe auf STM32 brauchen übrigens nur bedingt zwei Takte -> nämlich wenn man sie "back to back" ausführt. Dann stalled er. Macht man> dagegen dazwischen noch andere Befehle, dann ist das effektiv ein Takt.
Das ist mir neu. Hast du da eine Quelle? Das ist gerade einer der
Vorteile des M0+.
> Daß sich sbic 1:1 auf STM32 abbilden läßt, habe ich übrigens auch nicht> behauptet. Aber auch Deine Defizite im Lesen seien Dir nachgesehen. Daß> STM32 als load/store-Architektur das nicht kann, ist ja wohl klar.
Doch genau darum ging es. So viel zum Lesen. Der Befehl wird recht
häufig in vusb eingesetzt. Vor allem in der Synchronisierung.
avr schrieb:>> Portzugriffe auf STM32 brauchen übrigens nur bedingt zwei Takte ->> nämlich wenn man sie "back to back" ausführt. Dann stalled er. Macht man>> dagegen dazwischen noch andere Befehle, dann ist das effektiv ein Takt.> Das ist mir neu. Hast du da eine Quelle? Das ist gerade einer der> Vorteile des M0+.
Die STM32F0 sind aber nicht M0+, sondern M0. Dort hängen die GPIOs am
AHB, siehe Block Diagram im Datenblatt.
Die STM32L0 sind dagegen M0+. Einer der Vorteile des M0+ ist gerade, daß
die GPIOs nicht mehr am AHB hängen, sondern direkt am Core angebunden
sind und damit wirklich in 1 Takt angesprochen werden können.
Gerd E. schrieb:>> Das ist mir neu. Hast du da eine Quelle? Das ist gerade einer der>> Vorteile des M0+.>> Die STM32F0 sind aber nicht M0+, sondern M0.
Richtig, deswegen war ich auch irritiert. D.h wohl, dass ab M3 ein Cache
dazwischen hängt, mit dem Zugriffe doch nur ein Takt benötigen. Trifft
das auf alle busoperationen zu? Bisher dachte ich, dass nur
sequentieller Zugriff beschleunigt wird.
Viel Panikmache und Vermutungen im Thread...
Hier gibt es eine Software USB-Implementation für einen Cortex M0:
https://github.com/lemcu/LemcUSB
Da es fast nur bitbanging ist, sollte es sich auch auf andere CM0
portieren lassen.
USB 1.1 lässt sich problemlos mit einem einfachen logik-analyzer
debuggen. Die Saelae-Software hat z.B. einen Protokoll-Analyzer.
Eine gute Idee ist Software-USB auf einem Cortex aber trotzdem nicht...
Tim . schrieb:> Hier gibt es eine Software USB-Implementation für einen Cortex M0:
Cortex m0+, daher nicht ohne Änderungen portierbar.
Der Autor führt den kritischen Code im ram aus um definierte Laufzeiten
zu haben. In dem Fall würde mich immer noch interessieren, ob das Ganze
gleichzeitig auch mit dma funktioniert. Im Referenzmanual habe ich nicht
gefunden, wie der Bus arbiter funktioniert.
Ein logikanalyser mag zum Debuggen gehen - das interessante ist der
Protokoll Dekoder. Eigentlich braucht man da immer auch einen Aufbau für
die verwendete USB Klasse, wenn man effektiv arbeiten will.
avr schrieb:> Cortex m0+, daher nicht ohne Änderungen portierbar.>> Der Autor führt den kritischen Code im ram aus um definierte Laufzeiten
Stimmt. Ein LPC81X wäre für so etwas evtl. gut geeignet. Das ist ein M0+
mit zero flash waitstates bis 30 MHz.