NeoPixel und Arduino mit Lazarus

Benutzeravatar
Maik81SE
Beiträge: 220
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Ubuntu18.04; Pi4 (Lazarusfpcupdeluxe/FPC trunk Lazarus 2.0.12)
CPU-Target: x64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: NeoPixel und Arduino mit Lazarus

Beitrag von Maik81SE »

PascalDragon hat geschrieben:
Mo 6. Sep 2021, 09:46
Maik81SE hat geschrieben:
So 5. Sep 2021, 18:37
PascalDragon hat geschrieben:
So 5. Sep 2021, 11:37
Unit Intrinsics. Diese enthält noch ein paar weitere Intrinsics, die es vermeiden, dass man auf einen assembly Block für gängige Funktionalitäten zurückgreifen muss. ;)
Da verwendest du sicherlich eine andere als ich...
Ist tatsächlich nur in 3.3.1 verfügbar. So oder so würde ich dir aber vorschlagen mindestens auf 3.2.2 hoch zu gehen, da sich zwischen 3.0.4 und 3.2.0 vieles im AVR Bereich getan hat.
Gerade gesehen, das ich schon bei FPC 3.2.0 bin.

Wie ich aber auch zugeben muß, verwende ich noch FPCUPdeluxe V1.8.2r.
Sollte mir da nun auch mal ein Update saugen und ablegen.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 10.6 with Lazarus 2.1.0 r64080 & FPC 3.0.4 x86_64-linux-gkt2&Code:Blocks
Ubuntu 18.10 Studio
Pi4 -> Lazarus-IDE v2.0.0+dfsg-2 rDebian Package .0.0+dfsg-2[ & FPC 3.0.4

Mathias
Beiträge: 5118
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: NeoPixel und Arduino mit Lazarus

Beitrag von Mathias »

Fpcupdeluxe lohnt sich immer zu aktualisieren, ansonsten gibt es gerne das man kein fpc/Lazarus mehr bauen kann.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Maik81SE
Beiträge: 220
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Ubuntu18.04; Pi4 (Lazarusfpcupdeluxe/FPC trunk Lazarus 2.0.12)
CPU-Target: x64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: NeoPixel und Arduino mit Lazarus

Beitrag von Maik81SE »

hab mir gerade mal den Link in meine Lesezeichen geworfen...
un nur noch Erinnerung in's handy, das ich aller 6 bis 8 wochen mal schaue, ob es was neues Gibt.

Werd ich ja gleich sehen, was da raus kommt, und wenn es läuft, wie es soll, kann ich das gleich noch für den ATMega16 erweitern.
Hab ich gerade zufällig frische Testboards bauen lassen ;)

Ich hoffe nur, das meine Komponenten alle drinnen bleiben ;)

EDIT: 19:25
Update mit FPCUPdeluxe 2.0.1.

Cross AVR25/AVR5 aber die besagten Functionen/Proceduren sind nach wie vor nicht aufzufinden.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 10.6 with Lazarus 2.1.0 r64080 & FPC 3.0.4 x86_64-linux-gkt2&Code:Blocks
Ubuntu 18.10 Studio
Pi4 -> Lazarus-IDE v2.0.0+dfsg-2 rDebian Package .0.0+dfsg-2[ & FPC 3.0.4

sstvmaster
Beiträge: 473
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.0.12
CPU-Target: 32+64bit
Wohnort: Dresden

Re: NeoPixel und Arduino mit Lazarus

Beitrag von sstvmaster »

Maik81SE hat geschrieben:
Mo 6. Sep 2021, 18:45
...
Cross AVR25/AVR5 aber die besagten Functionen/Proceduren sind nach wie vor nicht aufzufinden.
https://gitlab.com/freepascal.org/fpc/s ... rinsics.pp

In trunk schon.
Windows 10, Lazarus 2.0.12 + Lazarus Trunk
LG Maik

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 913
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: NeoPixel und Arduino mit Lazarus

Beitrag von fliegermichl »

Da diese Neopixel Sachen Bestandteil eines größeren Projektes sind, habe ich die Neopixelsachen in ein separates Verzeicnis gepackt und dieses als Repository auf github geschoben.
https://github.com/fliegermichl/avr_neopixel

Wenn man da ein neues Repository anlegt, kann man wählen, ob eine initiale .gitignore angelegt werden soll. Dabei kann man einen "Typ" wählen. Da sind so Exoten wie Agda oder CFWheels wählbar aber weder FPC noch Lazarus. Wir sollten wirklich etwas mehr für die Bekanntheit tun :-)

hum4n0id3
Beiträge: 60
Registriert: So 5. Mai 2019, 15:23

Re: NeoPixel und Arduino mit Lazarus

Beitrag von hum4n0id3 »

Klasse gemacht :D

Für gitignore gibt es auch eine tolle Seite: https://www.toptal.com/developers/gitignore
Hier kann man sich eine gitignore erstellen lassen. Lazarus kennt die Seite übrigens und das kommt dann dabei raus:

Code: Alles auswählen


# Created by https://www.toptal.com/developers/gitignore/api/lazarus
# Edit at https://www.toptal.com/developers/gitignore?templates=lazarus

### Lazarus ###
# Lazarus compiler-generated binaries (safe to delete)
*.exe
*.dll
*.so
*.dylib
*.lrs
*.res
*.compiled
*.dbg
*.ppu
*.o
*.or
*.a

# Lazarus autogenerated files (duplicated info)
*.rst
*.rsj
*.lrt

# Lazarus local files (user-specific info)
*.lps

# Lazarus backups and unit output folders.
# These can be changed by user in Lazarus/project options.
backup/
*.bak
lib/

# Application bundle for Mac OS
*.app/

# End of https://www.toptal.com/developers/gitignore/api/lazarus
Die Seite habe ich mal gefunden als ich selbst Lazarus-Projekte Versioniert hatte :)

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 913
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.11 FPC 3.2)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: NeoPixel und Arduino mit Lazarus

Beitrag von fliegermichl »

Hab .gitignore eben entsprechend erweitert :-)

Benutzeravatar
Maik81SE
Beiträge: 220
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Ubuntu18.04; Pi4 (Lazarusfpcupdeluxe/FPC trunk Lazarus 2.0.12)
CPU-Target: x64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: NeoPixel und Arduino mit Lazarus

Beitrag von Maik81SE »

Bin gerade weiter dabei einige Fehler zu killen, welche aufgrund des unterschiedlichen Befehlssatzes AVR5(1) und AVR25 zustande kommen.

Der längere Weg ist dieser...

Code: Alles auswählen

{$if defined (ATMega328p)}
procedure TNeoPixel.show; assembler; nostackframe;
label wait, NextBit, NextByte, nop1, nop2, nop3;
asm
   push r29      // verwendete Register sichern
   push r28      // Y = r28/r29 fnumBytes
   push r27      // X = r26/r27 zeigt auf Pixels
   push r26      //
   push r18      // hi PinMask
   push r19      // lo PinMask
   push r20      // Bit Zähler
   push r21      // aktuell ausgegebenes Byte
   push r22      // next
   push r30      // Z = r30/r31 zeigt (vorerst) auf self
   push r31      // wird nach dem initialisieren gesichert und dann auf die Portadresse umgestellt
   push r24      // Das Ergebnis von canShow wird in r24 zurückgegeben
   push r25      // canShow verändert r24 und r25, benötigt aber den Zeiger auf self darin
wait:
   pop  r25
   pop  r24
   push r24
   push r25
   call canShow
   tst  r24
   breq wait
   pop  r25
   pop  r24
   movw  r30,r24                  // self in Z register laden
   ldd  r28,Z+TNeoPixel.fnumBytes   // fnumBytes in r28/r29 = Y Register laden
   ldd  r29,Z+TNeoPixel.fNumBytes+1
   ldd  r26,Z+TNeoPixel.fPixels  // Zeiger auf fPixels in X Register laden
   ldd  r27,Z+TNeoPixel.fPixels+1
   ldd  r22,Z+TNeoPixel.fPinMask
   ldd  r24,Z+TNeoPixel.fPin     // Arduino Pin
   ldd  r25,Z+TNeoPixel.fPin+1
   push r30                      // Z Register sichern. Wird von digitalReadPort überschrieben
   push r31
   call digitalReadPort          // Den aktuellen Zustand des Ports auslesen (wird in r24 zurückgeliefert)
   pop  r31
   pop  r30
   ldd  r18,Z+TNeoPixel.fPort    // Portadresse zwischenspeichern
   ldd  r19,Z+TNeoPixel.fPort+1
   push r30                      // Da wir nach dem senden der Sequenz 300us warten müssen,
   push r31                      // speichern wir den Inhalt des Z Registers auf dem Stack zwischen

   movw r30,r18                  // Portadresse in das Z Register laden.
                                 // ab hier kann nicht mehr auf self zugegriffen werden
   mov  r18,r24                  // Aktuellen Portzustand in r18 schreiben
   mov  r19,r18                  // und diesen auch nach lo schreiben
   or   r18,r22                  // Pin Bit setzen (hi)
   com  r22                      // Alle Bits ausser unserem setzen
   and  r19,r22                  // Pin Bit löschen, alles andere so lassen wie es ist
   com  r22                      // unser Bit wieder setzen, alles andere löschen
   ldi  r20,8                    // Bit Zähler
   ld   r21,X+                   // erstes Byte laden und X Register erhöhen
   mov  r22,r19                  // next := lo
   cli             // Interrupts sperren
NextBit:
   st   Z,r18      // PORT := hi                             (T =  0)
   sbrc r21,7      // if (Byte and 128) then                 (T =  2)
   mov  r22,r18    //   next := hi                           (T =  4)
   dec  r20        // Bit := Bit - 1                         (T =  5)
   st   Z,r22      // Port := next                           (T =  7)
   mov  r22,r19    // next := lo                             (T =  8)
   breq NextByte   // if Bit = 0 then NextByte               (from dec above)
   rol  r21        // Rotate Left on Byte                    (T = 10)
   rjmp nop1       // 3 Takte Pause                          (T = 11)
nop1:
   nop             //                                        (T = 13)
   st   Z,r19      // Port := lo                             (T = 15)
   rjmp nop2       // 3 Takte Pause machen
nop2:
   nop             //
   rjmp NextBit    // Nächstes Bit ausgeben
NextByte:
   ldi  r20,8      // Bit := 8
   ld   r21,X+     // Nächstes Byte von fPixels laden
   st   Z,r19      // Port := lo
   rjmp nop3       // 1 Takt warten
nop3:
   sbiw r28,1      // Bytezähler decrementieren
   brne NextBit    // Nicht Null? nächstes Byte ausgeben
   pop  r31        // die Adresse von self wieder zurück
   pop  r30        // holen
   sei             // Interrupts wieder zulassen
   call micros     // Aktuellen Microsekundenzählerstand in fEndTime speichern
   std  Z+TNeoPixel.fEndTime,r22
   std  Z+TNeoPixel.fEndTime+1,r23
   std  Z+TNeoPixel.fEndTime+2,r24
   std  Z+TNeoPixel.fEndTime+3,r25
   pop  r31        // gesicherte Register wieder herstellen.
   pop  r30
   pop  r22
   pop  r21
   pop  r20
   pop  r19
   pop  r18
   pop  r26
   pop  r27
   pop  r28
   pop  r29
end;
{$endif}

{$if defined (ATtiny45) of defined (ATtiny85)}
procedure TNeoPixel.show; assembler; nostackframe;
label wait, NextBit, NextByte, nop1, nop2, nop3;
asm
   push r29      // verwendete Register sichern
   push r28      // Y = r28/r29 fnumBytes
   push r27      // X = r26/r27 zeigt auf Pixels
   push r26      //
   push r18      // hi PinMask
   push r19      // lo PinMask
   push r20      // Bit Zähler
   push r21      // aktuell ausgegebenes Byte
   push r22      // next
   push r30      // Z = r30/r31 zeigt (vorerst) auf self
   push r31      // wird nach dem initialisieren gesichert und dann auf die Portadresse umgestellt
   push r24      // Das Ergebnis von canShow wird in r24 zurückgegeben
   push r25      // canShow verändert r24 und r25, benötigt aber den Zeiger auf self darin
wait:
   pop  r25
   pop  r24
   push r24
   push r25
   rcall canShow
   tst  r24
   breq wait
   pop  r25
   pop  r24
   movw  r30,r24                  // self in Z register laden
   ldd  r28,Z+TNeoPixel.fnumBytes   // fnumBytes in r28/r29 = Y Register laden
   ldd  r29,Z+TNeoPixel.fNumBytes+1
   ldd  r26,Z+TNeoPixel.fPixels  // Zeiger auf fPixels in X Register laden
   ldd  r27,Z+TNeoPixel.fPixels+1
   ldd  r22,Z+TNeoPixel.fPinMask
   ldd  r24,Z+TNeoPixel.fPin     // Arduino Pin
   ldd  r25,Z+TNeoPixel.fPin+1
   push r30                      // Z Register sichern. Wird von digitalReadPort überschrieben
   push r31
   rcall digitalReadPort          // Den aktuellen Zustand des Ports auslesen (wird in r24 zurückgeliefert)
   pop  r31
   pop  r30
   ldd  r18,Z+TNeoPixel.fPort    // Portadresse zwischenspeichern
   ldd  r19,Z+TNeoPixel.fPort+1
   push r30                      // Da wir nach dem senden der Sequenz 300us warten müssen,
   push r31                      // speichern wir den Inhalt des Z Registers auf dem Stack zwischen

   movw r30,r18                  // Portadresse in das Z Register laden.
                                 // ab hier kann nicht mehr auf self zugegriffen werden
   mov  r18,r24                  // Aktuellen Portzustand in r18 schreiben
   mov  r19,r18                  // und diesen auch nach lo schreiben
   or   r18,r22                  // Pin Bit setzen (hi)
   com  r22                      // Alle Bits ausser unserem setzen
   and  r19,r22                  // Pin Bit löschen, alles andere so lassen wie es ist
   com  r22                      // unser Bit wieder setzen, alles andere löschen
   ldi  r20,8                    // Bit Zähler
   ld   r21,X+                   // erstes Byte laden und X Register erhöhen
   mov  r22,r19                  // next := lo
   cli             // Interrupts sperren
NextBit:
   st   Z,r18      // PORT := hi                             (T =  0)
   sbrc r21,7      // if (Byte and 128) then                 (T =  2)
   mov  r22,r18    //   next := hi                           (T =  4)
   dec  r20        // Bit := Bit - 1                         (T =  5)
   st   Z,r22      // Port := next                           (T =  7)
   mov  r22,r19    // next := lo                             (T =  8)
   breq NextByte   // if Bit = 0 then NextByte               (from dec above)
   rol  r21        // Rotate Left on Byte                    (T = 10)
   rjmp nop1       // 3 Takte Pause                          (T = 11)
nop1:
   nop             //                                        (T = 13)
   st   Z,r19      // Port := lo                             (T = 15)
   rjmp nop2       // 3 Takte Pause machen
nop2:
   nop             //
   rjmp NextBit    // Nächstes Bit ausgeben
NextByte:
   ldi  r20,8      // Bit := 8
   ld   r21,X+     // Nächstes Byte von fPixels laden
   st   Z,r19      // Port := lo
   rjmp nop3       // 1 Takt warten
nop3:
   sbiw r28,1      // Bytezähler decrementieren
   brne NextBit    // Nicht Null? nächstes Byte ausgeben
   pop  r31        // die Adresse von self wieder zurück
   pop  r30        // holen
   sei             // Interrupts wieder zulassen
   rcall micros     // Aktuellen Microsekundenzählerstand in fEndTime speichern
   std  Z+TNeoPixel.fEndTime,r22
   std  Z+TNeoPixel.fEndTime+1,r23
   std  Z+TNeoPixel.fEndTime+2,r24
   std  Z+TNeoPixel.fEndTime+3,r25
   pop  r31        // gesicherte Register wieder herstellen.
   pop  r30
   pop  r22
   pop  r21
   pop  r20
   pop  r19
   pop  r18
   pop  r26
   pop  r27
   pop  r28
   pop  r29
end;
{$endif}
Ausschlag gebend für diesen Umständlichen Weg ist leider der Aspekt und da scheue ich mich auch nicht dies zuzugeben das ich nicht weiß, wie ich den Compilerschalter (MCU-Auswahl) in ASM hinbekomme.
mir persönlich wäre auch unter ASM folgender Weg angenehm.

Code: Alles auswählen

{$if defined (ATMega328p)}
   call canShow
{$endif}
{$if defined (ATtiny45) of defined (ATtiny85)}
  rcall canshow
{$endif}
Lediglich nachstehden Meldungen muß ich noch anfassen.

ATTiny85
/usr/bin/avr-ld: region `data' overflowed by 762 bytes

ATTiny45
/usr/bin/avr-ld: region `text' overflowed by 2540 bytes
/usr/bin/avr-ld: region `data' overflowed by 1018 bytes


Wenn dies vom Tisch ist, einmal Toasten und Testlauf, Änderungen Dokumentieren, bevor ich es in's git werfe.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 10.6 with Lazarus 2.1.0 r64080 & FPC 3.0.4 x86_64-linux-gkt2&Code:Blocks
Ubuntu 18.10 Studio
Pi4 -> Lazarus-IDE v2.0.0+dfsg-2 rDebian Package .0.0+dfsg-2[ & FPC 3.0.4

PascalDragon
Beiträge: 369
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: NeoPixel und Arduino mit Lazarus

Beitrag von PascalDragon »

Maik81SE hat geschrieben:
Mi 8. Sep 2021, 19:32
Ausschlag gebend für diesen Umständlichen Weg ist leider der Aspekt und da scheue ich mich auch nicht dies zuzugeben das ich nicht weiß, wie ich den Compilerschalter (MCU-Auswahl) in ASM hinbekomme.
mir persönlich wäre auch unter ASM folgender Weg angenehm.

Code: Alles auswählen

{$if defined (ATMega328p)}
   call canShow
{$endif}
{$if defined (ATtiny45) of defined (ATtiny85)}
  rcall canshow
{$endif}
Du solltest nicht nach MCU, sondern nach Prozessorart gehen, da die RTL auch für jeden kompiliert werden muss, aber nicht für jeden Mikrocontroller. Also zum Beispiel:

Code: Alles auswählen

{$if defined(CPUAVR5)}
{$elseif defined(CPUAVR25)}
{$endif}
Die unterstützten CPUs findest du mit fpc -Pavr -i und dann einfach CPU davor setzen für das Define.
FPC Compiler Entwickler

Benutzeravatar
Maik81SE
Beiträge: 220
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Ubuntu18.04; Pi4 (Lazarusfpcupdeluxe/FPC trunk Lazarus 2.0.12)
CPU-Target: x64; arm; avr
Wohnort: Lübeck
Kontaktdaten:

Re: NeoPixel und Arduino mit Lazarus

Beitrag von Maik81SE »

Ich
PascalDragon hat geschrieben:
Do 9. Sep 2021, 09:23

Du solltest nicht nach MCU, sondern nach Prozessorart gehen, da die RTL auch für jeden kompiliert werden muss, aber nicht für jeden Mikrocontroller. Also zum Beispiel:

Code: Alles auswählen

{$if defined(CPUAVR5)}
{$elseif defined(CPUAVR25)}
{$endif}
Die unterstützten CPUs findest du mit fpc -Pavr -i und dann einfach CPU davor setzen für das Define.
Ich gehe mal Stark davon aus, das es dann in der Summe so aussehen sollte?

Code: Alles auswählen

   {$if defined (CPUAVR5)}
   call canShow	//		--> wird ausgewählt, selbst wenn ATtinyx5 eingestellt ist 
   {$else if defined (CPUAVR25)}
   rcall canShow
   {$endif}
Lediglich diese Option erfüllt genau besagten Zweck, obgleich ich da bei eventuellen Änderungen/Erweiterungen alle MCUs händisch nachtragen muß.

Code: Alles auswählen

procedure TNeoPixel.show; assembler; nostackframe;
label wait, NextBit, NextByte, nop1, nop2, nop3;
asm
   push r29      // verwendete Register sichern
   push r28      // Y = r28/r29 fnumBytes
   push r27      // X = r26/r27 zeigt auf Pixels
   push r26      //
   push r18      // hi PinMask
   push r19      // lo PinMask
   push r20      // Bit Zähler
   push r21      // aktuell ausgegebenes Byte
   push r22      // next
   push r30      // Z = r30/r31 zeigt (vorerst) auf self
   push r31      // wird nach dem initialisieren gesichert und dann auf die Portadresse umgestellt
   push r24      // Das Ergebnis von canShow wird in r24 zurückgegeben
   push r25      // canShow verändert r24 und r25, benötigt aber den Zeiger auf self darin
wait:
   pop  r25
   pop  r24
   push r24
   push r25
   {$if defined (ATMega328p)}
   call canShow
   {$else if defined (ATtiny45) or (ATtiny85)}
   rcall canShow
   {$endif}
   tst  r24
   breq wait
   pop  r25
   pop  r24
   movw  r30,r24                  // self in Z register laden
   ldd  r28,Z+TNeoPixel.fnumBytes   // fnumBytes in r28/r29 = Y Register laden
   ldd  r29,Z+TNeoPixel.fNumBytes+1
   ldd  r26,Z+TNeoPixel.fPixels  // Zeiger auf fPixels in X Register laden
   ldd  r27,Z+TNeoPixel.fPixels+1
   ldd  r22,Z+TNeoPixel.fPinMask
   ldd  r24,Z+TNeoPixel.fPin     // Arduino Pin
   ldd  r25,Z+TNeoPixel.fPin+1
   push r30                      // Z Register sichern. Wird von digitalReadPort überschrieben
   push r31
   {$if defined (ATMega328p)}
   call digitalReadPort          // Den aktuellen Zustand des Ports auslesen (wird in r24 zurückgeliefert)
   {$else if defined (ATtiny45) or (ATtiny85)}
   rcall digitalReadPort
   {$endif}
   pop  r31
   pop  r30
   ldd  r18,Z+TNeoPixel.fPort    // Portadresse zwischenspeichern
   ldd  r19,Z+TNeoPixel.fPort+1
   push r30                      // Da wir nach dem senden der Sequenz 300us warten müssen,
   push r31                      // speichern wir den Inhalt des Z Registers auf dem Stack zwischen

   movw r30,r18                  // Portadresse in das Z Register laden.
                                 // ab hier kann nicht mehr auf self zugegriffen werden
   mov  r18,r24                  // Aktuellen Portzustand in r18 schreiben
   mov  r19,r18                  // und diesen auch nach lo schreiben
   or   r18,r22                  // Pin Bit setzen (hi)
   com  r22                      // Alle Bits ausser unserem setzen
   and  r19,r22                  // Pin Bit löschen, alles andere so lassen wie es ist
   com  r22                      // unser Bit wieder setzen, alles andere löschen
   ldi  r20,8                    // Bit Zähler
   ld   r21,X+                   // erstes Byte laden und X Register erhöhen
   mov  r22,r19                  // next := lo
   cli             // Interrupts sperren
NextBit:
   st   Z,r18      // PORT := hi                             (T =  0)
   sbrc r21,7      // if (Byte and 128) then                 (T =  2)
   mov  r22,r18    //   next := hi                           (T =  4)
   dec  r20        // Bit := Bit - 1                         (T =  5)
   st   Z,r22      // Port := next                           (T =  7)
   mov  r22,r19    // next := lo                             (T =  8)
   breq NextByte   // if Bit = 0 then NextByte               (from dec above)
   rol  r21        // Rotate Left on Byte                    (T = 10)
   rjmp nop1       // 3 Takte Pause                          (T = 11)
nop1:
   nop             //                                        (T = 13)
   st   Z,r19      // Port := lo                             (T = 15)
   rjmp nop2       // 3 Takte Pause machen
nop2:
   nop             //
   rjmp NextBit    // Nächstes Bit ausgeben
NextByte:
   ldi  r20,8      // Bit := 8
   ld   r21,X+     // Nächstes Byte von fPixels laden
   st   Z,r19      // Port := lo
   rjmp nop3       // 1 Takt warten
nop3:
   sbiw r28,1      // Bytezähler decrementieren
   brne NextBit    // Nicht Null? nächstes Byte ausgeben
   pop  r31        // die Adresse von self wieder zurück
   pop  r30        // holen
   sei             // Interrupts wieder zulassen
   {$if defined (ATMega328p)}
   call micros     // Aktuellen Microsekundenzählerstand in fEndTime speichern
   {$else if defined (ATtiny45) or (ATtiny85)}
   rcall micros     // Aktuellen Microsekundenzählerstand in fEndTime speichern
   {$endif}
   std  Z+TNeoPixel.fEndTime,r22
   std  Z+TNeoPixel.fEndTime+1,r23
   std  Z+TNeoPixel.fEndTime+2,r24
   std  Z+TNeoPixel.fEndTime+3,r25
   pop  r31        // gesicherte Register wieder herstellen.
   pop  r30
   pop  r22
   pop  r21
   pop  r20
   pop  r19
   pop  r18
   pop  r26
   pop  r27
   pop  r28
   pop  r29
end;
Umständlich, aber nach der ersten Variante immerhin ü120 Zeilen Code gespart.

Laut nachfolgender Info habe ich nur den AVR25 als Cross installiert.
FPCUPdeluxe V2.0.1 for x86_64-linux-gtk2 hat geschrieben:Welcome @ FPCUPdeluxe.
FPCUPdeluxe V2.0.1 for x86_64-linux-gtk2
Running on Ubuntu
CPU cores used: 4
Available physical memory: 3402 MB
Available swap: 2047 MB

Current install drectory: /home/vamlyktan/fpcupdeluxe

Got settings from install directory

Found crosscompiler for x86_64-windows
Found crosscompiler for avr-embedded-avr25

Fpcupdeluxe logging info:
fpcuplogger.batterybutcher.com/root/getinfohtml
fpcuplogger.batterybutcher.com/root/getinfohtml?ShowErrors=yes
Das sind erst mal kleine Feinheiten, Erst mal Speicherfresser finden und killen.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 10.6 with Lazarus 2.1.0 r64080 & FPC 3.0.4 x86_64-linux-gkt2&Code:Blocks
Ubuntu 18.10 Studio
Pi4 -> Lazarus-IDE v2.0.0+dfsg-2 rDebian Package .0.0+dfsg-2[ & FPC 3.0.4

Antworten