AVR Inline-Assembler und Ports

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.

AVR Inline-Assembler und Ports

Beitragvon Mathias » 26. Feb 2018, 23:08 AVR Inline-Assembler und Ports

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: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 27. Feb 2018, 18:30 Re: AVR Inline-Assembler und Ports

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
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Timm Thaler » 27. Feb 2018, 20:13 Re: AVR Inline-Assembler und Ports

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.
Timm Thaler
 
Beiträge: 707
Registriert: 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
Nach oben

Beitragvon kupferstecher » 27. Feb 2018, 22:31 Re: AVR Inline-Assembler und Ports

@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
kupferstecher
 
Beiträge: 165
Registriert: 17. Nov 2016, 11:52

Beitragvon Mathias » 28. Feb 2018, 17:52 Re: AVR Inline-Assembler und Ports

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: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 28. Feb 2018, 18:14 Re: AVR Inline-Assembler und Ports

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
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Timm Thaler » 28. Feb 2018, 22:36 Re: AVR Inline-Assembler und Ports

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.
Timm Thaler
 
Beiträge: 707
Registriert: 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
Nach oben

Beitragvon kupferstecher » 28. Feb 2018, 22:48 Re: AVR Inline-Assembler und Ports

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.
kupferstecher
 
Beiträge: 165
Registriert: 17. Nov 2016, 11:52

Beitragvon Mathias » 28. Feb 2018, 22:55 Re: AVR Inline-Assembler und Ports

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
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Timm Thaler » 28. Feb 2018, 23:08 Re: AVR Inline-Assembler und Ports

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?
Timm Thaler
 
Beiträge: 707
Registriert: 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
Nach oben

Beitragvon Mathias » 28. Feb 2018, 23:16 Re: AVR Inline-Assembler und Ports

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: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 1. Mär 2018, 18:58 Re: AVR Inline-Assembler und Ports

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
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon af0815 » 1. Mär 2018, 19:25 Re: AVR Inline-Assembler und Ports

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).
af0815
 
Beiträge: 3479
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon Mathias » 1. Mär 2018, 20:38 Re: AVR Inline-Assembler und Ports

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
Mathias
 
Beiträge: 4327
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon kupferstecher » 2. Mär 2018, 14:37 Re: AVR Inline-Assembler und Ports

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.
kupferstecher
 
Beiträge: 165
Registriert: 17. Nov 2016, 11:52

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Sonstiges



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried