AVR Inline-Assembler und Ports

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Mathias
Beiträge: 4851
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

AVR Inline-Assembler und Ports

Beitrag von Mathias »

Wieso geht mit diesem Assembler-Code, die LED nicht an, welche an einem Pin von PORTD hängt ( Arduino Pin 13) ?
Klammere ich die beiden obigen Zeilen aus, dann geht die LED an.

Code: Alles auswählen

program Project1;
begin
//  DDRB := 255;
//  PORTB := 255;
 
  asm
    ldi r16, 255
    out DDRB, r16
 
    ldi r16, 255
    out PORTB, r16
 
    .L1:
    jmp .L1
  end;
end.

Die Schleife mit L1 habe ich in einem anderen Code anstelle von

Code: Alles auswählen

repeat until false;
verwendet. Das hat funktioniert.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Ich bin ein bisschen weiter gekommen.

Bei dieser Assembler-Source, ist PORTB als 0x05 definiert.
https://github.com/DarkSector/AVR/blob/ ... 328def.inc

Folgender Code, schaltet die LED ein.

Code: Alles auswählen

begin
  DDRB := 255;
  asm
//    sei
//    ldi r16, 255
//    out 0x04, r16
 
    ldi r16, 255
    //    out PORTB, r16
    out 0x05, r16
 
    .L1:
    jmp .L1
  end;
end.

Mit DDRB, welche in der Assembler-Source mit 0x04 deklariert ist, funktioniert es nicht, nur mit PORTB.

Was mich bei PORTB verwundert, bei der ASM-Source, ist es als 0x05 definiert, und in der Pascal Unit Atmega328 als

Code: Alles auswählen

PORTB : byte absolute $00+$25;

Jemand eine Idee warum ?
Bei der C++ Source von Arduino, ist es auch als 0x05 deklariert.

Code: Alles auswählen

#define PORTB _SFR_IO8(0x05)
Wie kommt Pascal auf $25 ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1043
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Assembler und Ports

Beitrag von Timm Thaler »

Mathias hat geschrieben:Mit DDRB, welche in der Assembler-Source mit 0x04 deklariert ist, funktioniert es nicht, nur mit PORTB.


Was heisst "funktioniert nicht"? Bringt der Compiler eine Fehlermeldung, oder macht das Programm nicht, was Du glaubst was es machen soll? Und was glaubst Du soll es machen?

Mathias hat geschrieben:Wie kommt Pascal auf $25 ?


Nach einem halben Jahr hast Du aber schon mal das Datenblatt gefunden, oder? Seite 615, Register Summary.

kupferstecher
Beiträge: 269
Registriert: Do 17. Nov 2016, 11:52

Re: AVR Inline-Assembler und Ports

Beitrag von kupferstecher »

@Mathias:
Probiers mal mit dem Befehl STS anstatt mit OUT. Ich habs nicht probiert, aber ich meine, dass die Adressen unterschiedlich gemapt sind.

Also:
STS PortB, r16

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Mit sts geht es. Dieser Code schaltet mir die LED ein.

Code: Alles auswählen

begin
  asm
    ldi r16, 255
    sts DDRB, r16
 
    ldi r16, 255
    sts PORTB, r16
 
    .L1:
    jmp .L1
  end;
end.

Gemässe Google, hat out ein kleiner Adressraum als sts, das wird wohl der Grund am scheiten gewesen sein.

Nach einem halben Jahr hast Du aber schon mal das Datenblatt gefunden, oder? Seite 615, Register Summary.

Das Datenblatt ist bei Seite 442 fertig.
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf
Oder habe ich da etwas falsches erwischt ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Bei folgendem Code, motzt der Compiler

Code: Alles auswählen

sbi PORTB, 0B00010000 

mit folgedem Fehler:
Projekt kompilieren, OS: embedded, CPU: avr, Ziel: Project1: Exit code 256, Fehler: 1, Hinweise: 5

Code: Alles auswählen

Project1.pas(73,0) Error: Error while assembling exitcode 1

Ist dies ein Bug ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1043
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Assembler und Ports

Beitrag von Timm Thaler »

Mathias hat geschrieben:Das Datenblatt ist bei Seite 442 fertig.


Gibt halt verschiedene Versionen. Die Register Summary ist da auch drin, ab Seite 428.

"When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O Registers as data space using LD and ST instructions, 0x20 must be added
to these addresses..."

Der Hintergrund ist, dass Atmel ursprünglich für die Befehle "in" und "out" nur die Adressen 0..63 vorgesehen hat, weil das Befehlsspeicher spart (so wie auch adiw, sbiw oder ein ldd maximal 63 kann). Allerdings wurden es sehr schnell mehr als 64 in/out-Register, so dass man diese dann über ld / st wie den RAM ansprechen musste. Da allerdings auf den Adressen 0..31 die 32 Arbeitsregister liegen - ja, die kann man auch wie Ram ansprechen - durften die in / out Register erst ab Adresse 32 beginnen, was 0x20 entspricht. Daher die Verschiebung um 0x20, wenn man statt mit in / out mit ld / st auf die Ports zugreift.

Mathias hat geschrieben:Bei folgendem Code, motzt der Compiler
sbi PORTB, 0B00010000


Dein Port B hat 17 Pins? Impressive!

Bei sbi wird nicht die Bitmaske, sondern die Pinnummer angegeben, also: Setze Pin 4 in Port B => sbi PORTB, 4, gezählt von Null an. Mit google avr sbi kommt übrigens als erster Link die Seite, auf der der Befehl sbi erklärt wird. sbi PORTB, 4 geht ebenso wie sbi PORTB, 0B00000100. Natürlich nur, wenn PORTB definiert ist.

kupferstecher
Beiträge: 269
Registriert: Do 17. Nov 2016, 11:52

Re: AVR Inline-Assembler und Ports

Beitrag von kupferstecher »

Timm Thaler hat geschrieben:Natürlich nur, wenn PORTB definiert ist.

PORTB ist ja definiert, aber mit Offset 0x20.
Mann muesste also soetwas schreiben:
SBI PORTB - 0x20, 4

Als ich das das letzte Mal probiert hab, hat das aber nicht funktioniert, da hat sich der Compiler bei den Konstanten verrechnet.* In gleicher Weise koennte man dann auch den OUT-Befehl nutzen. IN/OUT ist doppelt so schnell wie LDS/STS, auch wenn der Unterschied nur ein Takt betraegt~


*Das waer wohl was fuer den Bugtracker.

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Vorhin wollt ich das Delay im Wiki von Timm probieren, auch dort hat der Kompiler, mit der gleicjen Meldung wie oben gemotzt.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1043
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: AVR Inline-Assembler und Ports

Beitrag von Timm Thaler »

kupferstecher hat geschrieben:PORTB ist ja definiert, aber mit Offset 0x20.


Ja, böse Fall. Hier würde der Compiler nichtmal meckern, weil 0x25 für PORTB noch im erlaubten Adressraum von 0..63 für sbi liegt. Man würde stattdessen TCCR0B verändern.

Mathias hat geschrieben:Vorhin wollt ich das Delay im Wiki von Timm probieren, auch dort hat der Kompiler, mit der gleicjen Meldung wie oben gemotzt.


Code?

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Morgen, wen der PC wieder läuft.

Das Problem war bei ldi oder ldd.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Code?

Ich habe es nochmals probiert, jetzt geht es auf einmal.

Ich gebe es zu, ich habe in der Zwischenzeit, den Cross-Compiler mit fpcupdelux neu gebaut.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4142
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: AVR Inline-Assembler und Ports

Beitrag von af0815 »

Mathias hat geschrieben:Ich gebe es zu, ich habe in der Zwischenzeit, den Cross-Compiler mit fpcupdelux neu gebaut.


BTW: Man kann sich auch die Logs von SVN oder GIT ansehen, da ist man dann nicht so überrascht. :-) Dort kann man die Änderungen schön verfolgen und bei manchen visuellen SVN Tools kann man sich das gant genau auch mit diff's ansehen was sich geändert hat.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: AVR Inline-Assembler und Ports

Beitrag von Mathias »

Dort kann man die Änderungen schön verfolgen und bei manchen visuellen SVN Tools kann man sich das gant genau auch mit diff's ansehen was sich geändert hat.
Im Forum wurde mal ein Tool vorgestellt, welches eine GUI dafür hat.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

kupferstecher
Beiträge: 269
Registriert: Do 17. Nov 2016, 11:52

Re: AVR Inline-Assembler und Ports

Beitrag von kupferstecher »

kupferstecher hat geschrieben:Als ich das das letzte Mal probiert hab, hat das aber nicht funktioniert, da hat sich der Compiler bei den Konstanten verrechnet.

Habs nochmal getestet, folgendes funktioniert:

Code: Alles auswählen

 
  OUT  PORTB+(-32),r16
  SBI  PORTB+(-32),4
 
  SBIS UCSRA+(-32),UDRE    //Warten bis UART data register (UDR) empty
    rjmp ...
 

Ist nicht schön, aber "in der Not" ist es besser als ne "Magik-Number" hinzuschreiben.

Antworten