Forum: Mikrocontroller und Digitale Elektronik AVRDU USB Inbetriebnahme scheitert.


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Georg P. (perthil)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich versuche gerade den USB von einem AVR32DU14 in Betrieb zu nehmen.
Es soll ein einfacher USB zu Seriell Wandler werden. Dazu habe ich mir 
eine kleine Platine gemacht. Der Controller ist 5V Bus powered. Die 5V
werden ueber einen TPS2041C gefuehrt um die Slewrate am VDD pin zu 
begrenzen.

Die Hardware ist Messtechnisch gesehen ok. VUSB liegt auf 3.3V und die 
Ruhepegel von DP (1) und DM (0) sind auch ok. Im 1ms Intervall kommt 
auch was auf DP und DM. Die Signale sehen besser aus als auf einem 
anderen USB zu Seriell Wandler mit einem (Fake)CH341.

Das Problem ist aber, dass das Geraet vom PC nicht gefunden wird. Es 
sieht so aus, als ob der AVR nicht antwortet. Auf dem Oszi sieht man 
immer nur Frames im Abstand von 1ms. Mit dem CH341 sieht man auch Mal 
eine Antwort. Vom AVR kommt nichts.

Im Anhang ist die Software als MPLABX 6.30 Project. Es ist eine 
abgespeckte und an den AVR32DU14 angepasste Version des Beispiels von 
Microchip (avr64du32-cnano-usb-cdc-to-usart-bridge-mplab-mcc) zu finden 
auf github.
Die angehaengte main.c ist das Orginal aus dem Microchip Beispiel.

Das Beispiel ist fuer den AVR64DU32 Curiosity Nano. Da der nicht Bus 
powered ist, habe ich alles rausgeschmissen was mit der Erkennung der 
USB-Versorgungsspannung zusammenhaengt.

Die Fehlermeldung in dmesg ist: device descriptor read/64, error -110

Im Netz findet man dazu, dass es wohl was mit dem Stromverbrauch zu tun 
hat.
Aber auch dass die Meldung ziemlich unspezifisch ist, und alles 
moegliche sein kann. Der Stromverbrauch jedenfalls kann es nicht sein, 
ich habe 5mA gemessen.

Sollte nicht der integrierte USB-Controller automatisch mit dem device 
descriptor antworten? Welchen Grund kann es geben, dass er das nicht 
macht?

Von dem Treiber fuer den AVR gibt es jedenfalls keine Fehlermeldung. 
Wenn da was waere sollte die LED blinken, sie ist aber permanent an.

Das Microchip Beispiel ist auch unvollstaendig. Ich habe nirgends was 
gefunden um die serielle Schnittstelle zu konfigurieren. Im USB Stack 
ist
zwar was dafuer vorgesehen, es wird aber nicht genutzt.

Vielleicht hat ja jemand schon Mal was mit dem AVRDU gemacht und kann 
mir da weiterhelfen. Vielleicht habe ich ja auch zuviel aus der main.c 
geloescht.

Viele Gruesse
von Jim M. (turboj)


Lesenswert?

Im Linux dmesg könnte man nachschauen ob D+ und D- vertauscht sind, dann 
erkennt Linux ein "low speed device".

Windows haut erst nach einer Minute oder länger eine Fehlermeldung raus, 
vorher würde man etliche Bus Resets sehen wenn man die USB 
Datenleitungen oszillosokopiert. Je nach Einstellung sieht man auch nur 
ein "?" im Gerätemanager.

Der USB Device Deskriptor muss vom µC Programm korrekt geliefert weden - 
dazu muss üblicherweise eine ganze Menge von internem Krams richtig 
gesetzt und bedient werden.

USB CDC hat keine "echte" serielle Schnittstelle. Man kann also den 
Linestate kommplett ignorieren (solange das Setup nicht in einen 
Fehlerzustand führt).
von Harald K. (kirnbichler)


Lesenswert?

Jim M. schrieb:
> Je nach Einstellung sieht man auch nur
> ein "?" im Gerätemanager.

Hilfreich ist hier der USB Device Tree Viewer von Uwe Sieber.

Der zeigt erheblich mehr an als der recht untaugliche Gerätemanager. 
Wenn man USB-Geräte entwickelt und mit Windows arbeitet, ist das das 
Tool der Wahl.
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Sollte nicht der integrierte USB-Controller automatisch mit dem device
> descriptor antworten?

Das ist kein „Controller“, der irgendwas jenseits des reinen 
Hardware-Handlings selbst macht. Der braucht für alles Software.

Bau dir Tracepoints in deinen Code rein, an denen du mit paar Pins 
wackelst, und schau dir auf einem LA an, wo du in der Software lang 
kommst. Das ist zumindest, was ich bei der Inbetriebnahme von USB auf 
MCUs bislang getan habe (nicht nur AVR, auch Cortex-M).
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jim M. schrieb:
> Im Linux dmesg

Er hat oben geschrieben, was dmesg meldet … also kein Windows.
von Georg P. (perthil)


Angehängte Dateien:

Lesenswert?

Jim M. schrieb:
> Im Linux dmesg könnte man nachschauen ob D+ und D- vertauscht sind, dann
> erkennt Linux ein "low speed device".

Es wird ein full speed device erkannt.

Jim M. schrieb:
> Der USB Device Deskriptor muss vom µC Programm korrekt geliefert weden -
> dazu muss üblicherweise eine ganze Menge von internem Krams richtig
> gesetzt und bedient werden.

Wenn ich Mal annehme, dass das Microchip Beispiel funktioniert, sollte 
es das bereits machen. Daran habe ich nichts geaendert. Das Beispiel 
wurde mit dem MCC (MPLab code configurator) erstellt. Den Controller 
konnte man im MPLab nicht aendern (es kam eine Fehlermeldung), also habe 
ich ein neues Projekt angelegt und mit dem MCC den USB-Teil identisch 
konfiguriert. Dort werden keine Events und Callbacks verwendet und der 
Treiber verwendet keine Interrupts. Das heisst fuer mich, dass der 
interne USB Controller das alles in Hardware macht. Dazu passt auch die 
Figure 27-4 aus dem Datenblatt (siehe Anhang).

Jim M. schrieb:
> USB CDC hat keine "echte" serielle Schnittstelle. Man kann also den
> Linestate kommplett ignorieren (solange das Setup nicht in einen
> Fehlerzustand führt).

Das mit dem Linestate ist wohl Microchip typisch. Die serielle 
Schnittstelle, die in den Curiosity Nano Debug Adaptern integriert ist, 
funktioniert auch nur dann, wenn der DTE vom PC aus gesetzt wird. 
Ausserdem wird im MCC ein Functional Descriptor Subtype ACM definiert, 
der sollte das wohl bereit stellen.

Jörg W. schrieb:
> Das ist kein „Controller“, der irgendwas jenseits des reinen
> Hardware-Handlings selbst macht. Der braucht für alles Software.

Anscheinend wohl doch. Ist auch ziemlich neu. Siehe auch oben.

Jörg W. schrieb:
> Bau dir Tracepoints in deinen Code rein, an denen du mit paar Pins
> wackelst, und schau dir auf einem LA an, wo du in der Software lang
> kommst. Das ist zumindest, was ich bei der Inbetriebnahme von USB auf
> MCUs bislang getan habe (nicht nur AVR, auch Cortex-M).

Im MCC gibt es fuer den USB Stack zwar ein paar Events/Callbacks, die 
werden aber nicht genutzt. Somit sollte der USB Controller im AVR das 
wohl doch selbst machen. Alles unter der Annahme, dass das Beispiel von 
Microchip wirklich funktioniert. Wo sollte man Tracepoints einbauen, 
wenn es gar keine Software gibt?
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Im MCC gibt es fuer den USB Stack zwar ein paar Events/Callbacks, die
> werden aber nicht genutzt. Somit sollte der USB Controller im AVR das
> wohl doch selbst machen.

Stimmt, dem muss man die Descriptoren wohl irgendwie im RAM hinterlegen.
von Georg P. (perthil)


Lesenswert?

Ich habe jetzt gefunden woran es liegt. Man muss USBDevice_Handle() in 
der main loop aufrufen. Dieser Aufruf war in USB_ConnectionHandler() 
versteckt, die ich rausgeloescht habe. Ich dachte sie waere nur dazu da 
um den USB ein- und auszuschalten, abhaengig davon ob der USB angesteckt 
ist. Leider falsch gedacht.

Vielen Dank fuer euere Antworten.

Jetzt muss ich nur noch herausfinden, wie man die serielle Schnittstelle 
ueber USB konfiguriert. Ich habe schon herausgefunden wo das lineCoding 
struct beschrieben wird (im USB_CDCRequestHandler). Das passiert immer 
beim open oder close der Schnittstelle (zumindest mit dem Programm 
CuteCom ist das so).

Aber es gibt keinen Callback um die Daten in die USART zu uebernehmen. 
Es gibt aber Funktionen um die einzelnen Elemente zu lesen 
(USB_CDCGetBaud() usw.).
Vielleicht gibt es ja fuer open/close einen callback? Mal sehen.

Oder weiss eventuell jemand Naeheres?

VG
von Veit D. (devil-elec)


Lesenswert?

Hallo,

also mein Ansatz wäre

> Vielleicht habe ich ja auch zuviel aus der main.c geloescht.
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Georg P. schrieb:

> Oder weiss eventuell jemand Naeheres?

Du hast doch die verdammten Sources. Lies' sie einfach. Wir müssten das 
auch bloß machen.
von Georg P. (perthil)


Lesenswert?

Ob S. schrieb:
> Du hast doch die verdammten Sources. Lies' sie einfach. Wir müssten das
> auch bloß machen.

Da hast du mich falsch verstanden. Ich erwarte nicht, dass jemand fuer 
mich dir Quellen liest. Das mache ich schon.

Aber es koennte ja sein, dass jemand hier schon Mal mit einem AVRDU 
gearbeitet hat und auch die lineCodings setzen musste. Ist ja nichts 
aussergewoehnliches. Der koennte mir dann evtl. einen Tipp geben wie man 
das machen kann.

Meine Suche in den Quellen ergab, das es keine Callbacks nach dem setzen 
der lineCodings gibt. Ich habe auch im MCC nichts gefunden womit man so 
etwas konfigurieren kann.

Von der KI kam dann man solle doch die generierte Datei aendern um 
entweder ein Flag oder einen callback einzubauen. Gar nicht schoen.

Also bleibt wohl nur die lineCodings zyklisch auszulesen um dann bei 
einer Aenderung die USART zu konfigurieren. Ist nicht die beste Loesung, 
sollte aber funktionieren.

Danke an alle.

VG
von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Georg P. schrieb:

> Jetzt muss ich nur noch herausfinden, wie man die serielle Schnittstelle
> ueber USB konfiguriert.

Du kannst Dir Inspirationen bei LUFA holen. Vom Beispielprojekt 
"USBtoSerial" habe ich mir schon die eine oder andere Anregung 
"ausgeliehen".

https://github.com/abcminiuser/lufa/blob/master/Projects/USBtoSerial/USBtoSerial.c

Grüßle,
Volker
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Ist nicht die beste Loesung, sollte aber funktionieren.

Finde ich als Idee ziemlich daneben.

Ich habe mir aber sowas auch lieber zu Fuß programmiert als mich auf 
solche Frameworks zu sehr zu verlassen.  Du hast ja einen Request, der 
vom USB dafür reinkommt, an den kannst du dann eine Aktion dranhängen.
von Georg P. (perthil)


Lesenswert?

Volker B. schrieb:
> Du kannst Dir Inspirationen bei LUFA holen. Vom Beispielprojekt
> "USBtoSerial" habe ich mir schon die eine oder andere Anregung
> "ausgeliehen".

Ich habe da Mal reingelesen. Um die USART zu programmieren wird auch ein 
Callback benutzt. Im MCC USB Treiber gibt es aber keinen Callback dafuer 
(oder ich habe ihn nicht gefunden) und am generierten Code moechte ich 
nichts aendern. Soweit ich gesehen habe wird der AVRDU auch nicht 
unterstuetzt.

Jörg W. schrieb:
> Finde ich als Idee ziemlich daneben.
>
> Ich habe mir aber sowas auch lieber zu Fuß programmiert als mich auf
> solche Frameworks zu sehr zu verlassen.  Du hast ja einen Request, der
> vom USB dafür reinkommt, an den kannst du dann eine Aktion dranhängen.

Das ist auch genau meine Meinung. Aber als ich das letzte Mal viel mit C 
programmiert habe war vor 30 Jahren mit Turbo-C unter DOS. Da wollte ich 
mich nicht gleich auf einen USB-Stack stuerzen. Ausserdem ist die Doku, 
die ich ueber USB gefunden habe, nicht gerade leicht verdaulich. Und bei 
der SW-Doku (meist erstellt mit Doxygen) wird zwar jede einzelne 
Funktion beschrieben, aber es steht nirgends wie, und in welcher 
Reihenfolge, man sie zu benutzen hat.


Da der Prozessor in meinem Fall nicht viel zu tun hat, und Aenderungen 
am lineCoding wohl nur beim open/close der Schnittstelle gesendet 
werden, ist
das zu verschmerzen. Ausserdem unterstuetzt die Hardware keine sehr 
hohen Baudraten, sie ist fuer 125kBaud ausgelegt. Mal sehen wie viel ich 
mit
dieser SW erreiche. Mir reicht so ca. 50kBaud.

VG
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.