Hallo Gemeinde,
ich arbeite gerade an meinem ersten XMega Projekt und stehe nun vor
folgender Aufgabe. Ein UART ähnliches Signal das an Pin C2 anliegt soll
in 99% der Zeit unverändert auf Pin C3 und C5 wieder ausgegeben werden.
Nur in machen fällen will ich - anstelle der direkten Ausgabe - selber
ein Signal aus dem µC ausgeben.
Nun könnte man der Einfachheit halber einen Ansatz wählen wie:
while(spiegeln) {PinC2=PINC3}
Allerdings ist das natürlich von der Systemlast her unsinn. Daher frage
ich mich, ob man diese Aufgabe nicht vom DMA Controller erledigen lassen
kann? Da ich selber noch nicht mit dem DMA gearbeitet habe weiß ich
nicht, wie ich diesen Einstellen und maskieren muss, damit nur die
betroffenen Pins permanent verarbeitet werden. Wobei permanent ja
eigentlich auch nicht richtig ist. Im Grunde würde es reichen bei jedem
Flankenwechsel den aktuellen Zustand zu spiegeln. So müsste die
Systemlast auf das notwendige Minium sinken.
Gruß Chris
Hi,
DMA uh oh, aber ich glaube der kann nur Byte weiße Daten schieben. ABER:
es müsste einen PIN Change interrupt geben bei den XMEGAS für alle Pins.
MfG
ich
Dann schalte C3 und C5 auf input und mit einem Analogschalter/Reed
Relais/Mosfet mit C2 kurz.
Nur für die 1% der Zeit unterbrichst du den Schalter, schaltest C3 und
C5 aus Ausgang und gibst deine Signale aus.
Nicht vergessen die Pins wieder auf Eingang/hochohmig zu Schalten bevor
du den Schalter wieder einschaltest.
Alternativ wie oben beschrieben ein Pin Change Interrupt, aber dann hast
du die Latenzzeit bis dein Interruptcode ausgeführt wird. Wie groß die
ist hängt davon ab on andere Interrupts ggf. den Pin Change sperren
können.
Die Idee mit dem externen Schalter hatte ich auch schon, ist aber
irgendwie die plain and boring Lösung und ist natürlich auch wieder ein
zusätzliches Bauteil.
Signal ist 500 kBit/s, also recht langsam und gemütlich. Jedoch ist die
Systemlast natürlich ein wichtiger Punkt, wenn man nur jedes 100000
Paket verlieren darf.
Peter Dannegger schrieb:> Chris N. schrieb:>> Signal ist 500 kBit/s, also recht langsam und gemütlich.>> Für eine Hardwarelösung ja.> In SW vergiß es.
Ein Xmega läuft mit maximal 32 MIPS. D.h. er führt zwischen den Flanken
64 Befehle aus. Das ist schon im Bereich des machbaren. Man muss halt
etwas kreativ mit der Software spielen....
@ Max D. (max_d)
>Ein Xmega läuft mit maximal 32 MIPS. D.h. er führt zwischen den Flanken>64 Befehle aus. Das ist schon im Bereich des machbaren. Man muss halt>etwas kreativ mit der Software spielen....
Stimmt schon. OK, sind wir mal kreativ. Nehmen wir SPI und lesen einfach
das Datenpin ein und schieben es gleich wieder über SPI raus. Macht bei
F_CPU/2 16 Msmps, bzw. etwas mehr 0,5us Verzögerung. Mit dem DMA kann
man das umkopieren wahrscheinlich machen. Wobei das nur bei einem UART
im SPI-Mode geht, das SPI-Modul ist nur im Slave Mode DMA-fähig (warum
auch immer 8-0)
Auf einem beliebigen Pin wird das aber eher schwierig.
Max D. schrieb:> Ein Xmega läuft mit maximal 32 MIPS. D.h. er führt zwischen den Flanken> 64 Befehle aus. Das ist schon im Bereich des machbaren.
Es reicht aber nicht, wenn keine Flanke verloren geht, die Pulsdauer
sollte auch einigermaßen stimmen.
Bei 10% Jitter ist die Erkennbarkeit der UART schon deutlich
herabgesetzt.
10% wären 6 Zyklen und selbst ein nackter Interrupt dauert schon 10.
Idealer Weise sollte eine Abtastung mit 16*Baudrate erfolgen, damit die
Störerkennung der UART noch greift (Abtastung bei 7/16, 8/16 und 9/16
Bitzeit).
Zum selbst steuern der Pins den DMA-CH abschalten.
Nach dem selbst steuern, die Pegel wieder wieder wie den Quell-Pin
setzten und den DMA-CH einschalten.
Wenn aber beim neu initialisieren zwischen Einlesen des Pegels am
Quell-Pin bis zum Einschalten des DMA eine Flanke erfolgt, wird es zu
einem invertierten Ausgangssignal kommen, da der DMA ins Toggle-Register
schreibt und diese Flanke verloren ging. Da muss man also schauen, wie
das Timing passt.
Gruss
Andre S. schrieb:> ja das geht (fast) wie gedacht.> Mit Event-System und DMA.
Wäre mal interessant, ob das auch in der Praxis klappt und die 500kBit
ohne größere Jitter oder Ausfälle durchkommen.
Und auch, wenn noch andere (low-Priority) Interrupts behandelt werden
müssen.
Asche über mein Haupt, ich hab mal wieder meinen eigenen Code nicht
richtig gelesen. Hab mir das noch mal angeschaut:
1
DMA.CH0.CTRLB=DMA_CH_TRNINTLVL_OFF_gc;
Es wird der DMA-CH-Interrupt gar nicht benutzt.
Der Channel läuft im Endlos-Mode, getriggert vom Event-Channel.
Das geht, da die Src- und Dest-Adressen nicht geändert werden müssen.
Jitter von Flanke zu Flanke hängt (eigentlich) nur davon ab, wie schnell
der DMA-Controller nach Trigger Zugriff auf das Bussystem bekommt.
Bei 125kbps funktioniert das bei mir.
500kbps ist aber schon eine Ansage. In der Tat sollte man das Timing
kontrollieren.
Nachtrag:
Hab auf dem Steckboard mal nachgeschaut (war noch aufgebaut):
Aus dem Funktionsgenerator 250kHz -> Es sind Ausreisser bis 2,6µs dabei.
(Sowohl Pulse aus auch Pausen)
Fazit: Geht wohl bis 125kbps, danach ist die Hardware für diese
Anwendung am Ende, und die Puls/Pausenbreite weicht zu sehr ab.
Falls dir ein Widerstand nicht zu viel HW ist:
Das Eingangssignal kommt an C2 und an einen Widerstands (etwa 1K). Den
anderen Anschluss des Widerstands kommt an C3 (dieser muss Tristate
fähig sein!). C3 bleibt in den 99% hochohmig. Falls du das Signal ändern
willst, schaltest du C3 als Ausgang und schickst deine Daten raus.
Anders ausgedrückt: Normalerweise wird das Signal über den Widerstand
weitergeleitet (unverändert). Ansonsten überschreibst du mit C3 das
Signal.
(C5 hab ich mal weggelassen)
Stefan1234 schrieb:> Falls dir ein Widerstand nicht zu viel HW ist:> Das Eingangssignal kommt an C2 und an einen Widerstands (etwa 1K). Den> anderen Anschluss des Widerstands kommt an C3 (dieser muss Tristate> fähig sein!). C3 bleibt in den 99% hochohmig. Falls du das Signal ändern> willst, schaltest du C3 als Ausgang und schickst deine Daten raus.
Oder die schöne Variante davon, einen Tristate-Buffer über den Enable
geschaltet und den uc-Pin passend komplementär als Tristate.
Stefan1234 schrieb:> Falls dir ein Widerstand nicht zu viel HW ist:
Nach drei Monaten wird er's doch hoffentlich geschafft haben, den
Pinzustand zu spiegeln.
Außerdem ist natürlich klar, dass man sowas mit Hardware immer
erschlagen kann; die Lösung rein in Software war deshalb die
Herausforderung.