Forum: Mikrocontroller und Digitale Elektronik STM32 USB init problem mit Kompaktcode von W.S.


von Alex (Gast)


Lesenswert?

Hallo Leute!

Ich versuche eine schlanke USB Schnittstelle auf einem STM32F042 zu 
implementieren.
Über den USB sollen kleine Datenpakete (Messwerte, wenige Bytes) etwa im 
Sekundentakt übertragen werden. Zu Konfigurationszwecken gibt es auch 
ein paar Parameter die über Terminal eingestellt werden sollen. Ist aber 
alles nicht Zeitkritisch.

Hab einen ST-Link V2 und arbeite mit CubeIDE.

Die Variante aus dem Code-Generator von ST (cubeMX) hab ich schon 
erfolgreich zum Laufen gebracht, allerdings ist mir die Implementierung 
zu groß.

Ich hab daher versucht, die Variante von 
http://stefanfrings.de/stm32/stm32l0.html (basierend auf der von W.S.) 
zu verwenden, kriege diese aber bei mir nicht zum Laufen.

Der Controller meldet sich am PC nicht an, scheinbar wird einfach 
garnichts übertragen.

Da meine C-Kompetenzen nicht gerade berauschend sind und ich mit USB 
bisher nichts zu tun hatte, hab ich versucht, die Ursache durch 
Vergleichen der cubeMX-Version mit der von W.S. zu finden.

Bisherige Erkenntnis:

Beim Initialisieren der USB-Register / Endpoint-Konfiguration sind die 
Schreib-Operationen auf die EPxR-Register nicht erfolgreich.
Die Register sind auch nach dem Schreiben noch leer.

Die Zeile

   USB_EP0R =
        ((3 << 12) |        /* STAT_RX = 3, also Empfang enabled */
        (2 << 4) |         /* STAT_TX = 2, also NAK erstmal     */
        (1 << 9) |         /* EP_TYPE = 1, also Control         */
        logEpCtrl);

in InitEndpoints(void) ist wirkungslos.

Ich dachte zuerst an ein Taktproblem und hab daher die Clock-Config 
vollständig von der cubeMX-Variante übernommen, um das als Ursache 
auszuschließen.

Interessanterweise funktioniert aber aucgh die cubeMX-Variante nur dann, 
wenn ich beim Initialisieren keine Breakpoints setze.
Mit Breakpoints ist es auch dort so dass ein Schreiben auf die EPxR 
wirkungslos ist, der Controller meldet sich garnicht am PC.


Hat jemand eine Idee woran das liegen könnte, bzw einen Ansatz zur 
weiteren Fehlersuche?

Vielen Dank,

Alex

von Stefan F. (Gast)


Lesenswert?

Alex schrieb:
> Die Zeile ... in InitEndpoints(void) ist wirkungslos.

Was genau meinst du mit "wirkungslos"?
Hast du den Pull-Up Widerstand an D+ hinzugefügt oder USB_BCDR_DPPU=1 
gesetzt (nicht beides zusammen!) ?
Stimmt der Name der ISR in usb.c (USB_IRQHandler) bzw. hast du ihn 
entsprechen deiner Interrupt-Vektor Tabelle angepasst?
Taktest du den USB Port mit dem 48MHz HSI Oszillator?
Hast du die USB Schnittstelle eingeschaltet?

> // Enable USB with pull-up
> SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN);
> SET_BIT(USB->BCDR, USB_BCDR_DPPU);

Du solltest dein Projekt in compilierbarer Form anhängen, damit wir 
nicht endlos viele Fragen stellen müssen und damit jemand dein Problem 
reproduzieren kann.

(Ich habe keinen STM32F0, deswegen kann ich es nicht ausprobieren).

> Interessanterweise funktioniert aber aucgh die cubeMX-Variante nur dann,
> wenn ich beim Initialisieren keine Breakpoints setze.

Die USB Schnittstelle muss permanent alle Events binnen weniger ms 
beantworten, deswegen fällt sie aus, sobald ein Breakpoint erreicht 
wird. Benutze zum Debugging lieber (serielle) Text-Meldungen.

von W.S. (Gast)


Lesenswert?

Alex schrieb:
> STM32F042

Du darfst nicht annehmen, daß ein Lowlevel-Treiber für den STM32F103 
einfach so auch auf einem STM32F042 funktioniert. Deshalb ist das 
gründliche Lesen des zum USB-Device gehörigen Kapitels in zutreffenden 
RefManual zwingend notwendig.

Stephanus hat meinen Treiber auf den STM32F303 umgeschrieben und im 
Prinzip müßtest du ihn auf den STM32F042 umschreiben. Jetzt hab ich das 
Manual für diesen µC nicht gelesen, kann dir also nicht sagen, ob da nur 
ne winzige oder eine umfängliche Anpassung nötig ist.

Eines ist aber klar: alle Vorbereitungen (Pinzuweisung, Takt richtig 
aufsetzen, richtigen Interrupt wählen, NVIC richtig aufsetzen) mußt du 
selber machen.

Ich hatte (wenn ich mich recht erinnere) auch ein Codestück zum 
Postmortem-Debugging beigefügt, das dazu dient, Meldungen, die man 
irgendwo in den Treiber einfügt, im RAM zwischenzuspeichern, so daß man 
diese von außerhalb des Treibers dann abfragen kann.

W.S.

von Alex (Gast)


Lesenswert?

Hallo Stefan und W.S.
Schon jetzt Danke für eure Hilfe und vor allem dafür, dass ihr euren 
Code für alle bereitstellt !!!!!


> Hast du den Pull-Up Widerstand an D+ hinzugefügt oder USB_BCDR_DPPU=1 gesetzt 
(nicht beides zusammen!) ?

ja, DPPU wird gesetzt, der PC reagiert darauf -> typische USB-Gerät 
nicht erkannt - Meldung; Der Controller tut sonst nichts mehr -> Enum. 
schlägt fehl

> Stimmt der Name der ISR in usb.c (USB_IRQHandler) bzw. hast du ihn entsprechen 
deiner Interrupt-Vektor Tabelle angepasst?

ja, ist beim F042 auch "USB_IRQHandler" und auch die Nummer ist 31

> Taktest du den USB Port mit dem 48MHz HSI Oszillator?

Der Takt kommt vom USB. Daher hatte ich auch zuerst ein Taktproblem 
vermutet und meine Takt-CFG komplett durch die vom cubeMX (die ja 
funktioniert) ersetzt. Da ist zwar jetzt die HAL involviert, aber ich 
kann zumindest ausschließen(nach meinem Kenntnisstand/bestem Wissen 
ausschließen), dass es da ein Problem mit der CLK-Config gibt. Alle 
Timer-Takte usw. hab ich geprüft und stimmen.

> Hast du die USB Schnittstelle eingeschaltet?+++

Die Einschalt-Prozedur ist die von W.S. Code, ich hab begonnen die 
einzelnen Schritte mit dem RefManual abzugleichen/zu verstehen und bin 
eben bis zu den Schreibzugriffen auf die EPxR-Register gekommen.


>> Die Zeile ... in InitEndpoints(void) ist wirkungslos.

>Was genau meinst du mit "wirkungslos"?

Das Register ist nach dieser Programmzeile immer noch 0, die Zeile hat 
keine Wirkung.
Das gilt für alle Zugriffe auf die EP-Register, Schreiben auf das 
CNTR-Register beispielsweise klappt....



> Die USB Schnittstelle muss permanent alle Events binnen weniger ms
> beantworten, deswegen fällt sie aus, sobald ein Breakpoint erreicht
> wird. Benutze zum Debugging lieber (serielle) Text-Meldungen.

Ich verstehe, dass es ab dem Zeitpunkt, an dem der Pullup gesetzt wird, 
zeitkritisch ist.
Hintergrund meiner Aussage war, dass beim cubeMX-code auch die 
EP-Register dann leer bleiben.
Meine Interpretation ist, dass die Konfiguration dieser in den IRQs 
durchgeführt wird, und nicht wie bei W.S. davor. Oder lieg ich da 
falsch?
Zugegebenerweise ist mir der cubeMX-Code extrem schwer nachzuvollziehen.


Ich stehe mit der ganzen Thematik ziemlich am Anfang, und hab einfach 
begonnen den Code und das RefManual Schritt für Schritt durchzuarbeiten.

Bis zu dem Punkt, an den ich gekommen bin, gab es imho keine nötige 
Anpassung für den F042. Die Schritte bis dorthin sind auch im Manual so 
beschrieben. Dass die EPxR nicht geschrieben werden, ist für mich 
einfach nicht nachvollziehbar/verständlich.

Alex

von Pieter (Gast)


Lesenswert?

Hallo Alex,

bitte die genaue Funktion der Register nachlesen.
Es ist schon spät..und so aus den alten grauen Zellen herraus:
CNTR löst z.B. Funkionen im USB-Core aus.
EP_R wird durch die USB-Core gesetzt ( z.B. USB-Empfang )und kann nur 
gelöscht werden.

Pieter

von W.S. (Gast)


Lesenswert?

Alex schrieb:
> Der Takt kommt vom USB.

Wiebitte?

Der Takt kommt normalerweise vom angeschlossenen Quarz per 
Quarzoszillator im Chip. Der muß angeworfen werden, dann die PLL und das 
richtige Teilerverhältnis in der Taktversorgung, so daß der 
USB-Peripherie-Core seine genauen 48 MHz kriegt.

Wenn das bei deinem Chip anders läuft, dann stehen mMn bei dir größere 
Änderungen am Treiber an, deren Umfang ich hier nicht abschätzen kann.

Ich habe aber ein anderes Negativbeispiel: Bei einem Kinetis (von 
Freescale, exakten Typ hab ich vergessen) ist die Taktversorgung per 
Quarz so schlecht (jittert), daß dort für den USB auf den internen 48 
MHz Takt aus einem RC-Oszillator zurückgegriffen werden muß. Da dieser 
jedoch frequenzmäßig zu instabil ist, muß er per Software auf die 
Signale vom Host am USB aufsynchronisiert werden, bevor irgend eine 
Kommunikation am USB möglich war. Als ich das gelesen hatte, war der 
Chip bei mir unten durch.

Also gönne deinem Chip einen passenden Quarz und benutze HSE+PLL. Alles 
andere halte ich für Pfusch, der nur mit Klimmzügen zum sauberen Laufen 
zu bringen ist. Wenn dein Chip für den USB als Takt einen HSI vorsieht, 
dann gibt es im USB-Core auch irgend welche Synchronisier-Tricks, die in 
meinem Code nicht vorgesehen sind.

W.S.

von Stefan F. (Gast)


Lesenswert?

Alex schrieb:
> Der Takt kommt vom USB

Das ist unklar. Das USB Kabel stellt kein Taktsignal zur Verfügung. Du 
musst den HSI Oszillator konfigurieren.

Alex schrieb:
> Die Einschalt-Prozedur ist die von W.S. Code

Der Code von W.S. schaltet das USB Interface nicht ein. Das musst du 
selber machen. Ich habe die beiden relevanten Zeilen oben zitiert.

Du steckst da viel Vertrauen in die HAL. Aber gerade weil du die HAL 
jetzt nur noch zum Teil verwendest, kann dabei durchaus etwas ganz 
anderes heraus kommen, als geplant. Das solltest du prüfen, insbesondere 
die Konfiguration von Taktversorgung und Interrupts.

Setze einen Unterbrechungspunkt in die Zeile "UsbSetup()" und prüfe den 
Inhalt aller relevanten Register.

Bedenke dabei, dass meine main.c von einer ganzen Reihe Default-Settings 
ausgeht, die der Chip beim Reset einstellt. Die HAL fummelt aber daran 
herum.

Alex schrieb:
> Das Register ist nach dieser Programmzeile immer noch 0, die Zeile hat
> keine Wirkung.

Klingt danach, als ob die entsprechende Funktionsgruppe im RCC nicht 
eingeschaltet ist.

Alex schrieb:
> Meine Interpretation ist, dass die Konfiguration dieser in den IRQs
> durchgeführt wird, und nicht wie bei W.S. davor. Oder lieg ich da
> falsch?

Keine Ahnung, wie das in der HAL umgesetzt wurde. Durch den 
Spaghetti-Code blicke ich nicht durch. Eine Initialisierung im Interrupt 
ist jedenfalls unwahrscheinlich, weil die ISR zwangsläufig erst nach der 
Initialisierung aufgerufen wird.

Hast du einen guten Grund, warum du deinen Quelltext immer noch nicht 
vorzeigst? Ich habe keine Lust, mich ohne Quelltext weiter in deinen 
Kopf hinein zu denken.

von Stefan F. (Gast)


Lesenswert?

W.S. schrieb:
> Wenn dein Chip für den USB als Takt einen HSI vorsieht,
> dann gibt es im USB-Core auch irgend welche Synchronisier-Tricks, die in
> meinem Code nicht vorgesehen sind.

Korrekt. Das ist im Reference Manual im Clock Recovery System 
beschrieben. Sollte man vielleicht mal lesen. Der STM32 synchronisiert 
seinen Oszillator ziemlich selbstständig mit den SOF Paketen vom USB 
Port, und das ist per Default nach dem Reset aktiv.

Aber die HAL fummelt erfahrungsgemäß gerne an den Default Werten herum, 
darüber bin ich bereits mehrfach gestolpert.

von Alex (Gast)


Lesenswert?

Vorweg: Es läuft (noch nicht voll getestet...)

Fehlerursache:

ich hatte im SYSCFG versehentlich das remap der Pins PA11 & PA12 
überschrieben.
Der F042 hat die USB-Pins als shared-pins ausgeführt, daher ist das 
remap nötig.

Lustigerweise kann man dann zwar beim USB alles mögliche initialisieren, 
aber die Schreibzugriffe auf die EPxR-Register gehen nicht.



Nochwas zum USB-Sync Takt:

Der F042 (und vmtl andere STM32 auch) haben ein CRS (clock recovery 
system), das den internen RC-Osc mit den SOFs des USB synchronisiert.
Die dafür nötigen Funktionen sind in Hardware implementiert und werden 
vor dem USB-Treiber initialisiert.

Ich hab mir diese Teile im Manual genau durchgearbeitet, die 
Konfiguration passt und funktioniert.

Mit dem USB-Treiber hat das nichts zu tun, der Takt läuft schon vorher.

Hab mir auch angesehen, wie das Ding auf Temperaturänderungen reagiert 
;-), ich würd sogar sagen, dass die CLK auf diese Weise stabiler* ist 
als mit einem normalen XO (eben wegen des tempcos).

*: genau genommen ist sie eigentlich nicht stabil, sie ist nur auf den 
USB synchronisiert -> optimal für eine stabile USB-Verbindung. Wenn man 
eine sehr exakte ReferenzCLK in der Schaltung benötigt (z.B: als 
Referenz für Messungen etc), ist das eher suboptimal.... aber darum 
gehts hier ja nicht.

Jedenfalls hab ich nirgends einen Hinweis gefunden, dass die 
Programmierung des USB-Treibers deshalb irgendwie angepasst werden 
müsste.

Zum Thema HAL:
ist mir auch nicht ganz geheuer, vor allem weil ich die vielen 
Unterprogramme extrem unübersichtlich finde.Hat aber sicher auch was mit 
meiner C-Schwäche zu tun...

Nur würde ich die HAL nicht als Spaghetti-Code bezeichnen, die ist wohl 
eher das Gegenteil davon....

Alex

von Guido Körber (Gast)


Lesenswert?

Die HAL ist ziemlicher Spaghetticode und erweckt bei mir den Eindruck, 
dass da Leute Angst vor Hardare haben und darum mehrere (sinnlose) 
Zwischenschichten eingezogen haben.

Wenn der Rechner sieht, dass ein Gerät versucht sich zu melden, wie weit 
ist denn der Protokollstack im Controller lauffähig? Kriegst Du irgend 
welche Requests und schickst Antworten raus?

von avr (Gast)


Lesenswert?

Guido Körber schrieb:
> Die HAL ist ziemlicher Spaghetticode und erweckt bei mir den Eindruck,
> dass da Leute Angst vor Hardare haben und darum mehrere (sinnlose)
> Zwischenschichten eingezogen haben.

Ist sie nicht. Es ist eher so, dass viele Leute bis heute nicht 
verstanden haben, dass die Zwischenschichten Abstraktionsschichten sind 
die bei richtiger Konfiguration des Compilers keinen (!) Overhead 
verursachen. Abstraktion ist sinnvoll und kostet heutzutage bei 
richtiger Verwendung weder Laufzeit noch Code. Ein USB-Treiber, von dem 
dagegen nichts direkt wiederverwendbar ist, ist nicht zeitgemäß (sorry 
W.S., aber so schreibt man moderne Software nicht).

von Stefan F. (Gast)


Lesenswert?

avr schrieb:
> Es ist eher so, dass viele Leute bis heute nicht
> verstanden haben, dass die Zwischenschichten Abstraktionsschichten sind
> die bei richtiger Konfiguration des Compilers keinen (!) Overhead
> verursachen.

Nein. Definitiv nicht.

Die HAL Funktionen belegen ein vielfaches des Flash Speichers, den man 
ohne HAL brauchen würde. Der USB CDC Treiber ist das beste 
Paradebeispiel dafür. Vergleiche den mal mit dem Werk von W.S., dann 
siehst du es.

> Ein USB-Treiber, von dem dagegen nichts
> direkt wiederverwendbar ist, ist nicht zeitgemäß

Das ist mir zu pauschal. Es gibt nicht nur den einen richtigen Weg.

von temp (Gast)


Lesenswert?

avr schrieb:
> Abstraktion ist sinnvoll und kostet heutzutage bei
> richtiger Verwendung weder Laufzeit noch Code. Ein USB-Treiber, von dem
> dagegen nichts direkt wiederverwendbar ist, ist nicht zeitgemäß (sorry
> W.S., aber so schreibt man moderne Software nicht).

Das ist auch nur die ausgeleierte Argumentation von Leuten die nur 
Arduino-Libs zusammen stöpseln. Die selben Argumente kamen als die 
STM-Libs noch nicht HAL hießen. Sie StdPerLib ist so schön portabel und 
man kann sie immer wieder verwenden. Und dann? Angeschissen wenn STM der 
Meinung ist die neuen MCUs bekommen nur noch die HAL. Und in 3 Jahren 
vielleicht wieder was neues.
Das einzige was sich nicht ändert sind die Register.

Mir ist so ein kompakter Code jedenfalls wesentlich lieber wie das ganze 
HAL-Geraffel. Und von wegen modern und zeitgemäß. Ich will vordergründig 
ein Problem lösen und nicht ein schönes modernes Programm schreiben. Wer 
ein paar Jahre auf dem Buckel hat, hat viele Säue durchs Dorf rennen 
sehen. Nur Idioten rennen jeder hinterher. Und STM hat schon einige Säue 
losgelassen...

Nachdem die NOP() Problematik im Code von W.S. eliminiert ist, ist er 
jedenfalls 1000mal besser als alle anderen mir bekannten 
Implementationen.

an Stefan ⛄ F. noch die Frage, hast du die von mir vorgeschlagene 
Änderung bezüglich der DoSetAddress() Funktion und der Eliminierung des 
letzten nötigen NOP()'s mal probiert?
Beitrag "Re: STM32F303 CAN und USB gleichzeitig"

von Stefan F. (Gast)


Lesenswert?

temp schrieb:
> hast du die von mir vorgeschlagene
> Änderung bezüglich der DoSetAddress() Funktion und der Eliminierung des
> letzten nötigen NOP()'s mal probiert?

Ja läuft, habe ich in meine Codebeispiele übernommen. Bitte 
entschuldige, dass ich vergessen habe, Feedback zu geben.

von Niklas Gürtler (Gast)


Lesenswert?

Funktioniert denn der Code aus meinem
USB-Tutorial mit STM32? Der hat jedenfalls kein NOP-Problem :)

von temp (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ja läuft, habe ich in meine Codebeispiele übernommen. Bitte
> entschuldige, dass ich vergessen habe, Feedback zu geben.

Ich hab mir gerade das Beispiel in STM32L073_usb_test.zip runtergeladen. 
Da steht noch
1
void DoSetAddress(void)
2
{
3
    ACK();    // das muß bei diesem Core davor!
4
    Nop(1000);
5
    USB_SetAddress(CMD.SetupPacket.wValue);
6
}
drin.

von Stefan F. (Gast)


Lesenswert?

temp schrieb:
> Da steht noch... drin

Misst, irgendwas habe ich da vergessen - offenbar.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Korrekt macht man das mit dem Adresse setzen so, dass man nach der 
Status Stage - d.h. nach dem Senden des leeren ACK Pakets, beim 
USB_ISTR_CTR-Interrupt - die Adresse übernimmt (DADDR Register), z.B.:
https://github.com/Erlkoenig90/f1usb/blob/minimal/src/usb.cc#L499

Dadurch passiert es exakt im richtigen Moment, und man blockiert nicht 
den Prozessor durch eine lange Nop-Schleife. Bei einer solchen ist die 
Dauer auch kritisch - ist sie zu lang, verpasst man das nächste Paket 
vom Host (ok, wird automatisch neu versucht), ist sie zu kurz, kommt das 
ACK nicht an.

Siehe auch:
https://www.mikrocontroller.net/articles/USB-Tutorial_mit_STM32#Adresszuweisung

von Thomas Z. (usbman)


Lesenswert?

Genau der SetAdressrequest ist die Ausnahme und funktioniert etwas 
anders als alle anderen Requests. Üblicherweise wird bei einem Requests 
erst dann mit ACK bestätigt wenn der Requests alle Aktionen bearbeitet 
hat. Bei SetAddress wird sofort bestätigt (unter der alten Adresse) und 
dann umgeschaltet allerdings erst wenn das ACK erfolgreich war. Nop ist 
nur ein Workarround für einen Fehler im Framework.

Thomas

von Stefan F. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Misst, irgendwas habe ich da vergessen - offenbar.

Thomas Z. schrieb:
> Nop ist nur ein Workarround für einen Fehler

Ist jetzt korrigiert.

Link zur Webseite: http://stefanfrings.de/stm32/index.html

von avr (Gast)


Lesenswert?

temp schrieb:
> avr schrieb:
>> Abstraktion ist sinnvoll und kostet heutzutage bei
>> richtiger Verwendung weder Laufzeit noch Code. Ein USB-Treiber, von dem
>> dagegen nichts direkt wiederverwendbar ist, ist nicht zeitgemäß (sorry
>> W.S., aber so schreibt man moderne Software nicht).
>
> Das ist auch nur die ausgeleierte Argumentation von Leuten die nur
> Arduino-Libs zusammen stöpseln. Die selben Argumente kamen als die
> STM-Libs noch nicht HAL hießen. Sie StdPerLib ist so schön portabel und
> man kann sie immer wieder verwenden. Und dann? Angeschissen wenn STM der
> Meinung ist die neuen MCUs bekommen nur noch die HAL. Und in 3 Jahren
> vielleicht wieder was neues.
> Das einzige was sich nicht ändert sind die Register.

- Ein Großteil der Arduino-Libs sind Käse, das Argument ist reine 
Polemik
- Die PeripheralLib war alles andere als kompatibel, die war eigentlich 
sehr Hardware-nah.
- Die HAL ist schon deutlich besser und wird sich so schnell nicht 
ändern.
- man kann sich durchaus seine eigene HAL schreiben, aber bitte nicht 
gleich das Applikation-Layer integrieren.

> Mir ist so ein kompakter Code jedenfalls wesentlich lieber wie das ganze
> HAL-Geraffel. Und von wegen modern und zeitgemäß. Ich will vordergründig
> ein Problem lösen und nicht ein schönes modernes Programm schreiben.

Darum geht es nicht. Es geht um Wartbarkeit, Wiederverwendbarkeit und 
Testbarkeit von Code.

Ich könnte den Code von WS in den wenigsten Fällen verwenden, obwohl ich 
sehr oft USB einsetze. Nur virtuelle COM-Ports habe ich eher selten aus 
USB-Klasse. Und daher setze ich auf Abtraktion, so dass ich nur einen 
sehr kleinen Teil austauschen muss, um die Klasse zu ändern. Auf der 
anderen Seite kann ich sehr einfach mehrere Klassen gleichzeitig 
implementieren.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Es gibt nunmal 2 Extrema in die man sich nicht begeben sollte.
Einerseits dem W.S. seinen Magic Number Code und dem aufgeblasenem HAL 
Code.
Der Lagenaufbau von sich des STM32HAL ist garnicht mal so schlecht, aber 
der Code selbst ist es.
zB wird in einem IRQ direkt an der Statemachine eines Task rumgefummelt 
und DANN wird eine Message geschickt zum Task aufzuwachen. WTF?

von temp (Gast)


Lesenswert?

Niklas G. schrieb:
> Korrekt macht man das mit dem Adresse setzen so, dass man nach der
> Status Stage - d.h. nach dem Senden des leeren ACK Pakets, beim
> USB_ISTR_CTR-Interrupt - die Adresse übernimmt (DADDR Register), z.B.:

Genau das habe ich am Code von W.S. geändert. Der Codeschnipsel oben ist 
der Zustand vor der Änderung. Alles weitere kann im verlinkten Thread 
nachgelesen werden.

avr schrieb:
> Ich könnte den Code von WS in den wenigsten Fällen verwenden, obwohl ich
> sehr oft USB einsetze.

Und ich habe bisher ausschließlich virtuelle COM-Ports verwendet, und 
dafür ist dieser schlanke Code ideal. Solange ich nichts anderes brauche 
besteht deshalb auch keine Notwendigkeit ein funktionierendes System 
(mit Fehlern) aufzuhübschen.

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.