Forum: Mikrocontroller und Digitale Elektronik USB udc_stop am SAM4E bleibt hängen


von Godi S. (godi22)


Lesenswert?

Hallo,

wie wird eine USB Verbindung mit dem ASF und SAM4E richtig beendet?

Ich habe eine USB CDC Verbindung welche sich auch aufbauen lässt und die 
Kommunikation funktioniert.
Will ich jedoch mit udc_stop die Verbindung trennen, dann treten 
folgende Probleme auf:

1) Wird ein USB Kabel welches µC und PC (ohne UART/VCOM Verbindung) 
verbindet, getrennt bevor udc_stop aufgerufen wird, dann bleibt beim 
Aufruf der µC in udp_clear_csr hängen.

2) Wird bei einer aufrechten UART/VCOM Verbindung das USB Kabel 
entfernt, dann bleibt ebenfalls udc_stop "hängen". Habe aber noch nicht 
herausgefunden wo hier das Problem liegt.

Gibt es dazu eine konkrete Vorgehensweise wie udc_stop richtig 
aufgerufen wird?
Oder kann generell udc_stop weggelassen werden?

von Adam P. (adamap)


Lesenswert?

Hey Godi,

ja das Problem mit dem hängen bleiben kenne ich ebenfalls.

Ich nutze USB Vendor, jeodch passiert(e) es bei mir ab und zu wenn der 
Host das Device deaktiviert hat.

Ich nutze das udc_stop nicht.
Ich lasse mein USB immer aktiv.

Das er hängen bleibt liegt wohl daran, das udp_clear_csr versucht Bits 
zu setzen, dies jedoch wohl nicht funktioniert - eine 100% Lösung habe 
ich noch nicht gefunden - aber versuch mal folgendes:
1
/*! Clears specified bit(s) in the UDP_CSR.
2
 *  \param ep   Endpoint number.
3
 *  \param bits Bitmap to set to 0.
4
 */
5
#define udp_clear_csr(ep, bits)            \
6
  do {                      \
7
    irqflags_t irq_flags;            \
8
    volatile uint32_t reg;            \
9
    irq_flags = cpu_irq_save();          \
10
    reg = UDP->UDP_CSR[ep];            \
11
    reg |= UDP_REG_NO_EFFECT_1_ALL;        \
12
    reg &= ~(bits);                \
13
    UDP->UDP_CSR[ep] = reg;            \
14
    while (UDP->UDP_CSR[ep] & bits);      \
15
    cpu_irq_restore(irq_flags);          \
16
  } while (0)

Würde mich interessieren, ob das bei dir etwas nützt.

: Bearbeitet durch User
von Godi S. (godi22)


Lesenswert?

Danke für deine Antwort!

Adam P. schrieb:
> Würde mich interessieren, ob das bei dir etwas nützt.

Ändert leider auch nichts.

Habe jetzt vorerst udc_stop auskommentiert, was mir in meiner Software 
leider einen weiteren Fehler bringt wenn die UART Verbindung aufrecht 
bleibt.

Muss noch versuchen wenigstens die UART Verbindung zu schließen.

von Adam P. (adamap)


Lesenswert?

Könntest du mir das Projekt evtl. zukommen lassen?
Würde gern selbst mal nachschauen / ausprobieren.

von Godi S. (godi22)


Lesenswert?

Kann ich dir leider nicht zukommen lassen, aber bei den ASF examples ist 
ein Projekt dabei, wo die selben Probleme auftreten:

USB Device CDC unit tests for SAM4E-EK

Bzw. das normale USB CDC Beispiel verwenden und udc_stop hinzufügen.

Ansonsten wäre ein Bug Report auch angebracht, bzw vielleicht besteht ja 
schon einer.

von Adam P. (adamap)


Lesenswert?

Also ich hab das mal eben aufgespielt:

1) CDC Unit Test
Da ist er hängen geblieben (beim anstecken an den PC).
Aber auch wenn er weiter lief, tauchte PC-seitig kein virtual COM Port 
auf.

Somit habe ich mich damit nicht weiter beschäftigt.

2) CDC Example
Meldet sich beim PC korrekt an und ob ich nun die Verbindung öffne oder 
nicht, ich kann das USB ziehen & stecken wie ich möchte, da passiert 
nichts.

Habe kein udc_stop() eingebaut...lediglich das Bsp. aufgespielt.

: Bearbeitet durch User
von Godi S. (godi22)


Lesenswert?

Hallo,
so jetzt habe ich einige Zeit mit Debugging verbracht und verschiedene 
Szenarien ausprobiert, da mir noch mehrere Probleme untergekommen sind.

Hauptproblem bei dem Framework ist, dass nicht überprüft wird ob ein 
USB-Kabel verbunden ist oder nicht.

Wenn das Kabel abgezogen wird, und danach eine Funktion zur 
Kommunikation aufgerufen wird (auch eine Änderung der Control-Signale), 
so bleibt das Framework in einer Endlosschleife hängen.

Die VBUS-Implementierung in udp_device habe ich leider auch nicht zum 
laufen bekommen => hier wird die Handler-Funktion nicht aufgerufen bei 
einer Änderung des VBUS.

Was aber funktioniert zur Detektierung ob ein USB-Kabel mit dem PC 
verbunden ist, ist UDC_SUSPEND_EVENT und UDC_RESUME_EVENT. Über diese 
beiden Callbacks habe ich ein "attached" flag gesetzt, welches ich 
Abfrage wenn eine Kommunikation stattfinden soll.

udc_stop habe ich aufgesplittet und folgend aufgerufen:
1
  udd_disable();
2
  if (usbAttached)  {
3
    udc_reset();
4
  }

Jetzt sollte es funktionieren.

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.