Forum: Mikrocontroller und Digitale Elektronik STM32 Problem beim "Senden" von Daten über USB


von Hannes M. (hannes_m)


Lesenswert?

Hallo zusammen,

Ich sitze seit einiger Zeit an einem Projekt ein USB Audio Device mit 
Sync EP aufzubauen. Im Groben und ganzen funktioniert auch alles schon, 
jedoch habe ich das Problem, dass oft nach dem Start der Übertragung der 
Audio-Daten (setzen von Alternate Settings = 1 für das Interface) es 
dazu kommt, dass die Sync Daten nicht übertragen werden nachdem ich 
versuche diese zu senden.

Das ganze äußert sich so, dass der PC durchaus den EP nach Daten 
abfragt, in der Antwort vom uC aber keine Nutzdaten vorhanden sind 
(Nutzdatenlänge = 0).
Nach einigen Aktivierungsversuchen des Interfaces überträgt er dann aber 
doch ein bis x mal die Sync Pakete korrekt. Dies ist jedoch völlig 
willkürlich und es gibt hier keine Regelmäßigkeit.

Anzumerken ist noch, dass ich mit den HAL-Librarys arbeite die bei 
Cube-MX von ST dabei sind.

Im Code vearbeite ich den EP aktuell so:
USB-Device Init:

  /* Open SYNC EP1 IN */
  USBD_LL_OpenEP(pdev, SYNC_IN_EP, USBD_EP_TYPE_ISOC, 3);
  pdev->ep_in[SYNC_IN1_EP & 0xFU].is_used = 1U;

USB-Device Setup:

if (alt_setting[0] == 1)
{
   USBD_LL_FlushEP(pdev, SYNC_IN_EP);
   USBD_LL_Transmit(pdev, SYNC_IN_EP, (uint8_t *)NULL, 0);
}

Im Callback:

USBD_LL_FlushEP(pdev, SYNC_IN_EP);
USBD_LL_Transmit(pdev, SYNC_IN_EP, (uint8_t *)haudio->sync_rate[0], 3);


Ich hoffe natürlich, dass ihr mir helfen könnt.

Gruß
Hannes

von W.S. (Gast)


Lesenswert?

Hannes M. schrieb:
> Anzumerken ist noch, dass ich mit den HAL-Librarys arbeite die bei
> Cube-MX von ST dabei sind.

Also im Klartext: Du kennst dich mit dieser Anwendung des USB nicht im 
Geringsten aus - und wilst dennoch damit ein Gerät bauen.

So wird das nix. Lies die diversen Dokumentationen, die du dir eben 
mühsam im Internet zusammenkratzen mußt und programmiere dein Zeugs 
selber.

Offenbar hapert es an der Zwischenpufferung der Audiodaten. Während der 
Host von sich aus seine Daten an das Device herunterpumpt, reagiert der 
betreffende EP-Handler in deinem µC falsch oder wird garnicht erst 
angesprochen, weil ihm das Pendant zum NAK_BI einen Streich spielt. 
NAK_BI ist der Interrupt, der (wenn er erlaubt ist) beim Bulk-EP bei 
jedem von der SIE an den Host gesendeten NAK (auf Nachfrage nach Daten 
zum Host hin) stattfindet. Erlaubt man ihn, dann steigt die 
Interrupt-Last deutlich, da so alle 11 µs (etwa, je nach USB-Last am 
Host) ein Interupt ausgelöst wird. Deshalb sollte man NAK_BI (oder 
dessen Gegentümer) normalerweise ausgeschaltet halten und nur ganz 
gelegentlich mal einschalten, damit der Bulk-IN bzw. dein Audio-IN ne 
Gelegenheit hat, nach einer Lücke im Datenverkehr wieder mit Senden 
anzufangen. Mach's am besten im Timer-Interrupt des USB (falls der 
Fehler daran liegen sollte).

W.S.

von Thomas (Gast)


Lesenswert?

nun da gibt es nur ein Problem wie macht man NAK auf ISO EPs?

Thomas

von Hannes M. (hannes_m)


Lesenswert?

Hallo W.S.

Ich denke schon, dass ich die USB Grundlagen verstanden habe, sonst 
würde mein Gerät ja garnicht funktionieren. Naja und da ich eben noch 
nicht alles weiß, frage ich natürlich hier im Forum, wenn ich durch die 
Dokumentationen im Internet nicht zur Lösung gelange. Ich muss aber 
tatsächlich gestehen, dass ich vorher nocht nicht wirklich etwas mit USB 
zutun gehabt habe (genau wie auch nicht mit dem STM32ern), aber 
irgendwann muss man sich ja auch mal an etwas neues wagen :).

Mittlerweile bin ich auf der Lösungssuche auch schon ein Stück 
weitergekommen. Wenn ich das korrekt sehe wird auf dem Feedback EP vom 
Host - je nach eingestellter SOF-Rate - ein Pipe Reset durchgeführt, der 
dann meinen TX Request zurücksetzt.

von Harry L. (mysth)


Lesenswert?

W.S. schrieb:
> Also im Klartext: Du kennst dich mit dieser Anwendung des USB nicht im
> Geringsten aus - und wilst dennoch damit ein Gerät bauen.
>
> So wird das nix. Lies die diversen Dokumentationen, die du dir eben
> mühsam im Internet zusammenkratzen mußt und programmiere dein Zeugs
> selber.

So ein Bullshit! - egal, wie oft du das herunterbeetest.

Wir leben im jahr 2019 und -gottseidank- muß man sowas heute nicht mehr 
selber machen.

Die USB-Stacks von ST funktionieren, und wenn nicht, ist es in 99% aller 
Fälle ein Layer-8-Problem.

Auch HAL muß man nämlich erstmal erlernen,und daß da beim 1. Versuch 
auch mal was schiefgeht, ist eher die Regel als die Ausnahme.

Aber das ist ja immer so....egal ob HAL oder bare-metal.

Ach ja W.S....bevor du jetzt wieder über "die Jugend von heute" 
schimpfst.
Ich bin eher in deinem Alter und arbeite auch seit Ende der 70er mit 
µCs, und bin heilfroh. daß es sowas wie HAL gibt, und ich mich meiner 
eigentlichen Aufgabe widmen kann.
Das war früher anders....

Und noch Eins:
Wer nicht mit der Zeit geht, geht mit der Zeit...

: Bearbeitet durch User
von Hannes M. (hannes_m)


Lesenswert?

Problem hat sich gelöst...

Ich habe statt dem EP-IN Callback den Sendeaufruf nun fest in den SOF 
Interrupt implementiert und nun tritt kein Synchronisationsfehler beim 
Beginn des Abspielens mehr auf.

von W.S. (Gast)


Lesenswert?

Thomas schrieb:
> nun da gibt es nur ein Problem wie macht man NAK auf ISO EPs?

'Man' macht es garnicht. Die SIE macht das ständig, und zwar dann, wenn 
sie vom Host gefragt wird "haste was?" und sie nix hat. 'Man' kriegt von 
alldem normalerweise nichts mit, es sei denn, man erlaubt der SIE, in 
solchem Falle einen Interrupt auszulösen.

Aber das ganze ist im Grunde ein "Katze beißt sich in Schwanz"-Problem. 
Wenn die SIE nichts hat für den Host, erzeugt sie normalerweise keinen 
Interrupt wenn sie dem Host NAK sagt, sondern sie erzeugt nen Interrupt 
nur einen bei ACK, um damit den nächsten Block an Daten zum Senden 
bereitzustellen. Ohne die Routinen im zuständigen EP-Handler hingegen 
werden jedoch die Puffer nicht gefüllt oder nicht als gefüllt und 
abholbereit markiert.

Und jetzt hat der TO das einzig Richtige gemacht: Er hat diesen Teil der 
EP-Behandlung verlegt, so daß er zumindest auch vom Tick her ausgeführt 
wird. Dann gibt es das Anlaufproblem nicht mehr und alles ist gut.

W.S.

von Thomas (Gast)


Lesenswert?

W.S. schrieb:
> Thomas schrieb:
>> nun da gibt es nur ein Problem wie macht man NAK auf ISO EPs?
>
> 'Man' macht es garnicht. Die SIE macht das ständig, und zwar dann, wenn
> sie vom Host gefragt wird "haste was?" und sie nix hat. 'Man' kriegt von
> alldem normalerweise nichts mit, es sei denn, man erlaubt der SIE, in
> solchem Falle einen Interrupt auszulösen.

natürlich macht man in der Firmware NAKs zB immer dann wenn der Bulk EP 
noch keine neuen Daten hat. Du brauchst mir USB nicht zu erklären das 
mach ich schon seit zwanzig Jahren auch mit Audio.
Das was du nicht verstehst ist das Audio auch die Sync EPs ISO sind und 
bei ISO gibt es eben kein NAK.

Thomas

von Jupp Kaltofen (Gast)


Lesenswert?

Noch einen etwas verspäteten Hinweis bezgl. der API "USBD_LL_Transmit" 
der St-Libs.

Da hat sich in 2015 eine Divergenz zwischen den Versionen ergeben, die 
bei Projekten mit dem Cube erzeugt wurden und den Libraries die als 
native STM32_USB_Device_Library bei ST geladen wurden. Das Argument size 
wird vom Cube mit uint16_t definiert.
Die geladenen Libraries aus gleichem Jahr 2015 hingegen definieren size 
als uint32_t.

Der Cube lieferte in erzeugten Projekten:
USBD_StatusTypeDef
USBD_LL_Transmit (USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t 
*pbuf, uint16_t size)

Beim LL_Receiver ist es genauso.


Es fällt nur auf wenn mal alte Projekte wiederverwerten will.

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.