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?
Gar keiner eine Idee? Anmerkung? Oder einen Beispielcode wie UART RX DMA mit unterschiedlichen Paketlängen funktioniert? Bin schon am verzweifeln :-(
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.