ATXmega: DMA und USART

Dec 06, 2013 9 Replies

Hallo,



kennt sich hier jemand mit dem ATXmega aus?



Ich arbeite gerade an einer Applikation auf einem ATXmega256A3, die Daten mißt.



Idealerweise könnte ich hier



a) sowohl sauber und mit Hardware-Flußkontrolle mit dem UART reden b) als auch zeitnah Messungen durchführen.



a) ist gegeben, aber dafür mußte ich den RX-Interrupt auf hohe Priorität setzen, den Timer-Interrupt für die Messung hingegen auf MED. (Mache ich es umgekehrt, gehen Bytes verloren.) Wenn ich dann ein komplettes Paket von 10, 20 oder noch mehr Bytes erhalte, deren Bearbeitung jeweils ca.



10 µs dauert, dann wird die Messung unter Umständen um 200 µs und noch verzögert. Bei einer Messfrequenz von 2 kHz sehr unschön.

Von daher war meine Überlegung, DMA zu verwenden, aber nur als "Sicherheitsnetz": die empfangenen Daten möchte ich gerne, sobald ich Zeit habe, verarbeiten. Habe ich keine Zeit, bleiben die Daten im Buffer.



Hier sehe ich aber einige Probleme:


  1. Laut Datenblatt kann ich ein Ereignis (wie etwa USART RXC) *entweder* einem Interrupt zuführen *oder* als DMA-Trigger verwenden. D.h., direkte Reaktion auf eingegangenes Byte ist nicht drin. Den DMA-Interrupt zu verwenden, fällt hier flach, weil ich nicht erst reagieren will, wenn die Transkation fertig ist, sondern wie gesagt schon früher. Das wäre wohl noch machbar, indem ich im Timer-Interrupt ab und zu mal nachschaue, ob was da ist, und ggf. ein Flag setze.


  1. Tue ich das aber, müßte ich die aktuelle DMA-Transaktion abbrechen, die Daten verarbeiten und dann DMA wieder aufnehmen. Da stellt sich mir die Frage, ob das sauber geht?

  2. Will ich das Ganze jetzt auch noch mit Flußkontrolle kombinieren und RTS hochziehen, wenn der Buffer zu voll wird, hörts ganz auf. Denn das zeitnah zu erledigen, wird schwierig. Hat da jemand eine Idee, oder denke ich nur zu kompliziert?

Sehr allgemeine Frage: Hat das schonmal jemand so getan und weiß, wie ich diese Probleme angehe? Gibts da ein HowTo oder so was?



Ich könnte auch mit Mini-DMA-Transaktionen von 1 Byte arbeiten, die Daten irgendwo hinschreiben lassen und dann über ein Event direkt RTS setzen, bis ich das Byte verarbeitet habe. Aber da weiß man nicht, ob die Gegenseite auch sofort aufhört mit Senden, wenn ich RTS setze. Von daher, ebenfalls recht diffizile Angelegenheit.


Am 06.12.2013 19:17 schrieb Thomas Rachel:

Letzteres geht ja gar nicht. Das Event-System ist wohl doch nicht so mächtig, wie es zunächst scheint...

Thomas

Am 06.12.2013 19:17, schrieb Thomas Rachel:

Naja, auskennen ist übertrieben... ich habe schonmal mit dem DMA gearbeitet, allerdings in einem etwas anderen Kontext. Die Sachen sind teilweise eher schlecht als recht dokumentiert, insbesondere das DMA double buffering hat mich fast zum Wahnsinn getrieben. Viel trial und error...

Um ehrlich zu sein, würde ich mir in Deiner Konstellation den ganzen Stress mit dem DMA beim Empfangen von Bytes nicht geben. Es sei denn, Du hast eine sehr hohe Datenübertragungsrate zu realisieren.

Vlt. wäre es eine Alternative für den Empfang eine kleine ISR zu implementieren, die einen (Ring-)Buffer und den Hardware-Handshake (RTS) übernimmt.

Die eigentliche Datenverarbeitung würde ich tatsächlich entweder direkt im Hauptprogramm machen, also "pollen" ob Daten im Ringbuffer zur Auswertung vorliegen, oder aber in der RX ISR (sofern der XMega das kann, das habe ich jetzt gerade nicht im Kopf) einen "Software-Interrupt" mit low Prio auslösen und die Datenauswertung in der entsprechenden ISR erledigen.

Grüße Markus

Diese E-Mail ist frei von Viren und Malware, denn der avast! Antivirus Schutz ist aktiv. http://www.avast.com

Wenn ich dann ein komplettes Paket

Deine Eckdaten höhren sich nicht so an als wäre unbedingt DMA nötig. Wie lange dauert eine Messung? Darf während der Messung ein 2us langer interrupt ausgeführt werden?

Du könntest dann die Daten per Interrupt in einen Ringpuffer schreiben. Um auf den Interrupt zu reagieren hast du eine ganze Bytelänge auf dem Comport Zeit.

MFG Gernot

Am 07.12.2013 10:00, schrieb Gernot Fink:

Und der OP sollte gründlich überlegen, ob er wirklich Hardware-Flusskontrolle benötigt. Das macht das ganze meist nur unnötig kompliziert.

Wie hoch ist überhaupt die Datenrate auf dem UART und wie lange dauert die Messung?

Gruß

Stefan

Nein.

Ich sehe jetzt nich so wirklich, wieso man bei 2kHz Abtastrate DMA brauchen sollte - wenn Du im RX-Interrupt nur die Daten in einen Ringpuffer schreibst und bei Bedarf RTS setzt, sollte das ausreichend schnell gehen.

Ist der Jitter, der dadurch in den Abtastzeitpunkten entsteht, wirklich kritisch bei der Anwendung?

Wenn ja: Datenerfassung im Timerinterrupt und UART pollen in der Hauptschleife - dann schafft das auch ein Atmega8 locker.

cu Michael

Am 06.12.2013 23:51 schrieb Markus:

Oh ja.

"sehr hoch" ist relativ... es sind 460800 bit/s.

Das tue ich bereits...

Thomas

Am 07.12.2013 10:00 schrieb Gernot Fink:

Naja, derzeit funktioniert es auch so leidlich, aber ich sehe da dennoch Verbesserungspotential.

Die CLKADC liegt bei 125 kHz, d. h. der "Propagation Delay" liegt bei

Manchmal hat man einen Knoten im Hirn. Danke schonmal :-)

Thomas

Am 07.12.2013 10:37 schrieb Stefan:

Ohne DMA ist es absolut nicht kompliziert; erst das Zusammenspiel aus DMA und HW-FC ist wirklich kompliziert. Von daher werde ich das mit dem DMA vorerst mal bleiben lassen.

Messung triggern und Messung auswerten voneinander entkoppele, komme ich

implementiere.

Thomas

Am 07.12.2013 15:14 schrieb Michael Schwingen:

Nur bei hoher Interrupt-Prio, und nur wenn andere HI-Interrupts kurz

Thomas

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required