Hallo.
Ich will mit einem STM32F0 Daten (DMX) versenden und brauche zwischen
den gesendeten Bytes ein einstellbares delay (0-800us).
Bei 0 (das was ich jetzt habe) Sende ich alles per DMA raus und gut ist.
Aber ich habe bemerkt das der eine oder andere Empfänger damit Probleme
hat.
Warum auch immer, das müssen wir hier auch nicht klären.
Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?
Irgendwas in Prozessor Hardware wäre mir am liebsten dafür.
Halt etwas was mir keine Performance schluckt.
Peter
Peter schrieb:> Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?
Nein, denn der DMA ist ja gerade dafür da möglichst schnell ohne
Prozessorlast Daten zu schaufeln.
Peter schrieb:> Irgendwas in Prozessor Hardware wäre mir am liebsten dafür.
Wie wäre es mit den guten alten Interrupts? Damit ist dein Problem
optimal gelöst, und "es schluckt dir keine Performance".
BTW: Erst Programmieren lernen, dann Datenblätter lesen und verstehen
lernen (in diesem Fall heisst es "Reference Manual") und dann erst
Gedanken über "Performance" machen. Diese Vorgehensweise hat sich über
Jahrzehnte bewährt...
Man könnte per Timer in regelmäßigen Abständen einen DMA-Transfer
auslösen, der immer nur ein Byte in den UART Puffer überträgt. Wenn der
Timer die 512 erreicht (Überlauf interrupt) ist der gesamte Transfer
fertig.
Programmierer schrieb:> in regelmäßigen Abständen einen DMA-Transfer> auslösen, der immer nur ein Byte in den UART Puffer überträgt.
Und wo genau liegt dann der Vorteil des DMA??? Ein Byte kann man genauso
im INT in den TX-Buffer legen und man spart sich die Konfiguration bzw.
Start des DMA.
Frage mich weshalb jeder so scharf auf den DMA ist, ohne aber die
eigentliche Funktionsweise zu verstehen.
Programmierer schrieb:> Wenn der> Timer die 512 erreicht (Überlauf interrupt) ist der gesamte Transfer> fertig.
Das musst du mal bitte näher erklären.
@ Peter (Gast)
>Ich will mit einem STM32F0 Daten (DMX) versenden und brauche zwischen>den gesendeten Bytes ein einstellbares delay (0-800us).
Nö. DMX kann die Daten LÜCKENLOS senden. Die einzige Lücke ist zwischen
den DMX-Zyklen. Die kann man aber leicht mit einem Timer generieren.
>Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?
Mit einem Umweg über einen Timer, ja.
>Irgendwas in Prozessor Hardware wäre mir am liebsten dafür.>Halt etwas was mir keine Performance schluckt.
Mein Gott, dein STM32 hat genug Power, das alles ohne DMA zu machen. Das
kann selbst ein kleiner AVR.
@ Dennis (Gast)
>Und wo genau liegt dann der Vorteil des DMA???
Datentransfer ohne CPU-Belastung.
> Ein Byte kann man genauso>im INT in den TX-Buffer legen und man spart sich die Konfiguration bzw.>Start des DMA.
Kostet aber CPU-Zeit (Interrupt), die ggf. was wirklich dringendes zu
tun hat.
>Frage mich weshalb jeder so scharf auf den DMA ist, ohne aber die>eigentliche Funktionsweise zu verstehen.
Ist halt trendy ;-)
Es ist leider so das einige billige DMX Lampen es nicht mal schaffen
diese alte DMX Norm einzuhalten. Darum ist es leider notwendig ein
Interbyte-Delay einzubauen.
Das der Sinn vom DMA der ist schnell Daten zu transportieren und das
unabhängig vom Prozessor ist mir klar.
Ich hatte halt nur gehofft das es einen Trick gibt dem ein Delay rein zu
würgen. So wie waitstates beim RAM, nur mit mehr zeitlichem Spielraum.
Timer mag ich nicht so weil ich schon etliche Interrupts am laufen habe.
Aber dann werde ich hier wohl oder übel an den Prioritäten drehen bis
alles ohne Jitter läuft.
Peter
@ Peter (Gast)
>Ich hatte halt nur gehofft das es einen Trick gibt dem ein Delay rein zu>würgen. So wie waitstates beim RAM, nur mit mehr zeitlichem Spielraum.
Nicht gelesen? Oder nicht verstanden?
>>Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?>Mit einem Umweg über einen Timer, ja.
Normalfall:
DMA schaufelt direkt auf den UART -> Daten werden lückenlos gesendet.
"Trick":
DMA wird über einen Timer ausgelöst -> Daten werden im Zeitraster mit
Lücken gesendet, trotzdem muss die CPU nicht arbeiten.
Ob man das beim STM32 so hinkriegt, muss man prüfen. Die ATXmegas können
es, weil man dort als Triggerquelle Hardwarevents angeben kann.
>Timer mag ich nicht so weil ich schon etliche Interrupts am laufen habe.
Timer ja, aber nicht klassisch per Interrupt sondern als Triggerquelle
fpr die DMA!
>Aber dann werde ich hier wohl oder übel an den Prioritäten drehen bis>alles ohne Jitter läuft.
Was für großartige Dinge musst du denn noch so machen? Und gerade das
Senden von DMX verträgt problemlos Jitter.
Falk Brunner schrieb:> Ob man das beim STM32 so hinkriegt, muss man prüfen.
Ja, natürlich. Sonst wäre DMA da ja ziemlich sinnlos. (Nicht nur) die
Timer können DMA Events auslösen und dadurch Transfers starten.
Welche billigen DMX-Lampen brauchen denn so ein Delay? Ein ordentlicher
DMX-Empfang war doch schon vor 20 Jahren in der 8051-Steinzeit möglich.
Viele Grüße, Stefan
Stefan schrieb:> Welche billigen DMX-Lampen brauchen denn so ein Delay? Ein ordentlicher> DMX-Empfang war doch schon vor 20 Jahren in der 8051-Steinzeit möglich.
DMX schreibt 2 Stopbits vor und nicht 1. Ich hab ihn schon drauf
hingewiesen aber er antwortet ja nicht.
Es sind leider recht viele Lampen die nicht mal heute es schaffen
250Kbaud sauber rein zu holen.
Warum? Wie gesagt das werden wir hier nicht klären können, braucht Euch
nur mal in den einschlägigen Licht Foren um zu hören.
Auch 2 Stopp Bits helfen nicht immer!
Das sind auch nur 4us, was wie gesagt nicht immer reicht.
Ich hatte nicht daran gedacht das man den Timer ja auch ohne Interrupt
benutzen kann.
Das vereinfacht das ganze.
Wie ich das nun zum laufen bringe werde ich sehen, kann ja nicht so
schwer sein.
Ich hoffe das der DMA auch das Zählen der Bytes dann noch machen kann
wenn ich den über einen Timer triggere.
Alternativ hatte ich mir schon überlegt nur aus den Timerinterrupt
direkt zu senden. Aber die andere Lösung scheint mir die eleganteste
Methode zu sein.
Danke Euch,
Peter
Hallo,
du hast doch sicher einen "Heartbeat", einen Timer mit festem Raster, in
dem du alles möglicher erledigen kannst, ich habe sowas eigentlich immer
für 1 ms und 10 ms, da sendest du dann halt neben deinen sonstigen
Aufgaben jedesmal ein Byte über DMX, wenn eines zu senden da ist.
Einfach und kostet praktisch nichts.
Georg
Peter schrieb:> 1ms Raster und 250Kbaud?>> Wie soll das gehen?
Thread lesen - er will es ja gerade langsamer haben. Und die 1ms sind ja
nicht in Stein gemeisselt.
Ich glaube auch nicht, dass er soviele Lampen hat, dass er den Durchsatz
von 250 kBaud braucht. Aber was weiss man schon genau.
Georg
Beim DMA kannst Du angeben, wieviel Übertragungen er machen soll. Danach
schaltet er sich ab und macht einen DMA-ready-Interrupt.
Für das danach folgende Break musst Du warten, bis der UART idle ist.
(WichtiG: der DMA meldet Dir "fertig", sobald er alle Bytes an den UART
geschaufelt hat, der UART ist dann aber noch mit dem letzten Byte
beschäftigt, also warten, bis der auch idle ist).
Für den Break ist es eine gängige Methode, den UART auf eine niedrigere
Baudrate (z.B. 100kbaud) zu setzen und ein Null-Byte zu senden. Wenn der
UART danach wieder idle wird, wieder die 250kbaud einstellen und den
nächsten Frame senden.
Gruß, Stefan
Peter schrieb:> Kann man dem DMA sagen das er eine Pause machen soll zwischen den Bytes?
Neben den bereits gezeigten Möglichkeiten gibt es die Möglichkeit zwei
DMAs aufzusetzen. Einen der einen Timer füttert, der Timer löst eine DMA
Update Event aus und er DMA schreibt einen weiteren Wert in den Timer.
Die Werte werden in einer Liste gehalten und können dort flexibel
eingestellt werden.
Der zweite DMA reagiert auch auf ein Event desselben Timers und
transferiert den Buffer in die UART. Ist HW-nah wie gewünscht, belastet
die CPU im Transfer nicht (nur wenn die Listen verändert werden müssen)
bedeutet aber beim Aufsetzen entsprechend Performance.
Ich sehe aber nicht den Vorteil der Lösung gegenüber einer
interrupt-gesteuertene Übertragung da Du die Listen auch verändern musst
und das felxibel im Transfer. Würde ich unter den gegebenen Umständen
per INT machen und nicht per DMA.
rgds
Da ich ein Interface bauen will muss ich auch die kompletten 512 Byte
senden.
Bevor jemand fragt, das ist nicht mein erstes. Hatte vorher immer avr
benutzt und da die timer Interrupt Methode benutzt.
der Prozessor war mir aber für rdm zu langsam .
Der m0 passt da besser und die dma timer Methode wird jetzt eingebaut.