Forum: Mikrocontroller und Digitale Elektronik LPC17xx UART RX mit DMA


von Thomas Haslinger (Gast)


Lesenswert?

Hallo,

bräuchte Hilfe:

Mit meinem LPC1758 muss ich große Datenmengen empfangen (ca. 300kByte/s 
mit 6,5MBaud). Wenn ich es über Interrupt mache ist mein  Controller 
eigentlich die meiste Zeit ausgelastet immer in die Interrupts zu 
springen, deswegen woltle ich es über DMA machen.

Problem: Ich weiß nicht wielange die Pakete sind, die ich empfangen soll 
und auf die ich dann reagieren muss, weiß nur dass sie zwischen 20 und 
255 Byte sind)
Deswegen hab ich die DMA Übertragungsgröße auf 255 gesetzt und schreibe 
in einen 255 Byte Puffer.
In meiner Hauptschleife, schau ich dann immer nach, ob das 1.  Byte 
schon geschrieben ist (darin steht auch die Gesamtlänge des Pakets drin)
Somit weiß ich wo das letzte Byte stehen muss und ich schaue nach, ob 
darin schon die ENDE-Kennzeichnung steht.
Somit weiß ich, mein Paket habe ich empfangen.
Dann schalte ich den DMA Kanal aus und wieder ein, damit er beim 
nächsten Byte wieder an die Startadresse des Puffers schreibt.

Soweit funktioniert das auch, wenn zwischen den Paketen mind. 4ms 
liegen, kommen sie schneller passiert es immer wieder, dass der DMA die 
neuen Bytes oben im Puffer anfügt, anstatt von der Startadresse neu 
anzufangen?

Irgendjemand eine Idee oder bessere Lösung wie man das mit den variablen 
Paketlängen lösen könnte?
Gibt es beim DMA ein Register oder so wo ich auslesen kann, wieviele 
Bytes mir der DMA schon vom RX geschickt hat?

von Thomas Haslinger (Gast)


Lesenswert?

Gar keiner eine Idee? Anmerkung?
Oder einen Beispielcode wie UART RX DMA mit unterschiedlichen 
Paketlängen funktioniert?
Bin schon am verzweifeln :-(

von (prx) A. K. (prx)


Lesenswert?

Thomas Haslinger schrieb:

> Gibt es beim DMA ein Register oder so wo ich auslesen kann, wieviele
> Bytes mir der DMA schon vom RX geschickt hat?

Dem Manual nach ist das TransferSize Feld im channel control register 
auslesbar und liefert ebendiese Information. Bei aktivem channel nicht 
unbedingt exakt, aber das sollte hier kein Problem sein.

von (prx) A. K. (prx)


Lesenswert?

Ein mögliches Schema bei solchen DMA Anforderungen geht round robin mit 
zwei Puffern. Ist der eine Puffer voll wird per Ende-Interrupt auf den 
anderen geschaltet. Stehen die hintereinander, dann entsteht so ein 
round robin Puffer, in dem der Frame allerdings nicht bündig liegt, 
sondern irgendwo mitten drin, und auch mal von hinten nach vorne 
rüberklappt.

von (prx) A. K. (prx)


Lesenswert?

Eine weitere Variante käme bei dir möglicherweise in Frage: Das erste 
Byte eines Frames per Interrupt abholen und in der ISR das DMA mit nun 
bekannter Länge aktivieren. Wenn du dann mit zwei sich abwechselnden 
Puffern arbeitest, dann kannst du einen Frame verarbeiten während der 
andere bereits einläuft.

von Thomas Haslinger (Gast)


Lesenswert?

Vielen Dank, das mit dem Interrupt und dann darin den DMA mit bekannter 
Größe aktivieren hört sich interessant an und werd ich ausprobieren.

Ich hoffe nur der Interrupt kommt schnell genug, bei meiner jetzigen 
Methode wo ich mittels RX Interrupt abfrage, kommt es bei 6,5MBaud immer 
wieder mal vor, das der Hardware FIFO nicht schnell genug gelehrt werden 
konnte.
Da kam der Interrupt ab und zu viel zu spät, obwohl auch kein anderer 
Interrupt aktiviert ist. Kanns mir selber nicht erklären warum.

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.