: "r" (curbyte), "x" (&ws2812_PORTREG), "r" (mask), "r" (~mask)
21
);
22
}
23
}
Frage 1:
Die variable "ctr" brauch ich nicht, aber wenn ich die zeile rausnehme
reklamiert der compiler. Ich versteh die syntax nicht.
Frage 2:
1
while (datlen--)
2
{
3
curbyte=*data++;
Sollte auch in asm sein um das timing genau einzustellen. KA wie ich in
asm einen pointer auf ein array auslese. Funktioniert zwar ohne, aber
ein delay zwischen den bytes ist sichtbar.
Trulla O. schrieb:> aber wenn ich die zeile rausnehme> reklamiert der compiler.
Du schreibst nicht welche Zeile du "rausnimmst".
Du schreibst nicht wie der Compiler "reklamiert".
Wie wär's wenn du präzise Angaben machst?
Trulla O. schrieb:> Es geht um folgenden code
Es ist immer ne ganz schlechte Idee, Code aus dem Kontext heraus zu
reißen.
Magst Du mal den Ursprung verlinken. Da ist bestimmt beschrieben, was
dieser Code überhaupt machen soll.
Und der Autor wird sich bei "ctr" auch was gedacht haben.
:: "r" (curbyte), "x" (&ws2812_PORTREG), "r" (mask), "r" (~mask)
und %nummer um eins reduzieren da weniger parameter.
Warum hier ST 16-bit-pt verwendet wird und nicht OUT 8-bit-pt ist mir
nicht klar. Mit OUT bring ich das nicht zum laufen.
Jetzt noch *data in einen 16-bit-pt laden und von dort lesen ...
Trulla O. schrieb:> und %nummer um eins reduzieren da weniger parameter.>> Warum hier ST 16-bit-pt verwendet wird und nicht OUT 8-bit-pt ist mir> nicht klar. Mit OUT bring ich das nicht zum laufen.
Warum meinst du, ohne einen Hauch von Kenntnissen zum Thema Inline-ASM
dort rumschrauben zu müssen? Die Funktion hast du irgendwo her kopiert,
sie funktioniert. Was soll das Ganze?
Das original ist das aus der ws2812_light library.
Wozu das ganze ändern? Das original steuert 1 pin, einen string von LED.
Ich möchte aber 7 strings von LED ansteuern. 7 mal schneller. Die
chinesen bauen damit audio spektrum displays.
Es geht darum 7 serielle signale zu produzieren, nicht nur eines. Und du
wirst zugeben müssen das ist ziemlich genial ✨
Ja, das funktioniert bereits, es geht darum das zu optimieren /
verstehen. Wahrscheinlich ist bei OUT das timing zu schnell ...
Da fragt man was und alle antworten sind ziemlich demotivierend. ausser
dem hier:
Falk B. schrieb:> Ich auch nicht ;-)
Trulla O. schrieb:> Warum hier ST 16-bit-pt verwendet wird und nicht OUT 8-bit-pt ist mir> nicht klar.
Weil sie offenbar nicht garantieren können oder wollen, dass das
Portregister auch tatsächlich im per OUT adressierbaren Bereich liegt.
"ctr" wird im Original gar nicht benutzt und daher vom Compiler eh
wegoptimiert.
Trulla O. schrieb:> Ich möchte aber 7 strings von LED ansteuern. 7 mal schneller.
Dann ist es in der Tat das Einfachste, du folgst Falks Rat und schreibst
das Ding komplett neu in Assembler und linkst es zum C-Code dazu.
Trulla O. schrieb:> Das original ist das aus der ws2812_light library.>> Wozu das ganze ändern? Das original steuert 1 pin, einen string von LED.> Ich möchte aber 7 strings von LED ansteuern. 7 mal schneller. Die> chinesen bauen damit audio spektrum displays.
Ich hab da meine Zweifel, daß ein AVR-Arduino dafür die richtige Wahl
ist. Denn das Konzept beruht darauf, daß die CPU den Datenstrom vorher
berechnet und in den RAM schreibt. Die Funktion gibt die nur aus. Dazu
braucht es aber ne MENGE an RAM. Und ob das dann schneller ist als der
Standardansatz mit einem Bit, ist fraglich. Für größere CPUs, vor allem
ARM mit DMA etc. gibt es solche Mehrkanalfuntkionen, die auch wirklich
mehr Leistung bringen.
WS2812 Ansteuerung
Oliver S. schrieb:> UNd ich würds ja in C schreiben.
Was gleich noch mit den Vorteil hat, dass der Compiler automatisch OUT
benutzt, wenn der Port im dafür erreichbaren Bereich liegt.
Falk B. schrieb:> Dazu> braucht es aber ne MENGE an RAM. Und ob das dann schneller ist als der> Standardansatz mit einem Bit, ist fraglich.
Es braucht 12.5% mehr ram wie die 1-bit variante. Und es ist 7 mal
schneller. Wenn alle 8 pins eines ports rausgeführt wären wäre ram 1:1,
speed 8 fach.
Motivationsvideo: https://www.youtube.com/watch?v=2p-FsQTYz1Q
Trulla O. schrieb:> Geht nicht. Aber mit 3 nop gehts. 🤩🤩🤩
Was dann ja auch deine Frage beantwortet, warum im Original st und nicht
out verwendet wurde. Irgendwie muß man die Zyklen anscheinend
verballern.
Oliver
Trulla O. schrieb:> Es braucht 12.5% mehr ram wie die 1-bit variante. Und es ist 7 mal> schneller.
Nö. Das ist die Milchmädchenrechnung, vor der ich gewarnt habe. Die
AUSGABE ist 7x schneller! Aber vorher mußt du die Daten berechnen! Wie
lange dauert das?
> Wenn alle 8 pins eines ports rausgeführt wären wäre ram 1:1,> speed 8 fach.
Bla.
Beitrag "Re: Frage zu IR-Remote+LED-Strips an AVR"
Die Funktion brauch keine Umrechnung, da werden die RGB Daten direkt
ausgegeben und auch in Echtzeit berechnet.
Oliver S. schrieb:> Irgendwie muß man die Zyklen anscheinend> verballern.
Man muss ein relativ genaues Timing einhalten. Schneller bringt da nix,
außer Farbfehlern.
Trulla O. schrieb:> Jetzt brauch ich noch einen vernünftigen "datendreher".
Das sind 5x8=40 LEDs. Bei 800kbit/s und 24 Bit/LED sind das 1,152ms für
einen Update mit einer Datenleitung. Das die Dinger intern sowieso nur
mit ca. 400Hz PWM arbeiten, ist ein Update in weniger als 2,5ms sinnlos.
Für einen Equalizer sowieso, denn 400Hz Bildrate braucht kein Mensch,
20-100 reichen.
D.h. bei 100Hz LED-Refresh bleiben dir "nur" ~8,8ms bzw. 88% CPU Last
übrig, um die Daten für die LEDs zu berechnen.
Trulla O. schrieb:> Jetzt brauch ich noch einen vernünftigen "datendreher".
40 LEDs zu je 60 mA brauchen 2,4 A. Vergleiche das mal mit den
technischen Daten deines Arduino Boardes oder der USB Spezifikation.
Beo B. schrieb:> asm volatile ("nop \n\t nop \n\t nop");
Wenn du den Reset eh schon in C machst, kannst du auch gleich
_delay_us() benutzen. Das bezieht dann auch gleich die Taktfrequenz mit
ein, um entweder eine passende Anzahl von NOPs zu generieren oder eine
entsprechende Schleife.
Wenn es auf's Zyklen zählen ankommt, würde ich dem C-Compiler nicht
vertrauen, da ist man bei echten Assemblerbefehlen doch eher auf der
sicheren Seite.
chris_ schrieb:> Wenn es auf's Zyklen zählen ankommt, würde ich dem C-Compiler nicht> vertrauen, da ist man bei echten Assemblerbefehlen doch eher auf der> sicheren Seite.
Kannst du aber, delay_us() kriegst du selbst nicht besser hin.
chris_ schrieb:> da ist man bei echten Assemblerbefehlen doch eher auf der sicheren> Seite.
Nur dass du dir die eben für jede CPU-Taktfrequenz selbst zusammen
basteln musst, während der Compiler das für dich automatisch berechnen
kann. Kleiner als zyklengenau kann er es natürlich auch nicht :-), aber
das kann er schon. Nicht, weil ein Compiler grundsätzlich besser wäre,
sondern weil ihm diverse fleißige Programmierer das mal beigebracht
haben.
(Diese Aussage trifft in der Form erstmal auf den AVR zu. Bei anderen
Architekturen ist das sicher anders oder gar nicht so machbar.)