Arduino DUO läuft fast mit Lazarus.

siro
Beiträge: 572
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Arduino DUO läuft fast mit Lazarus.

Beitrag von siro »

Grade mal gesucht,
ich habe tatsächlich eine sam3x8e.pp gefunden.
Sehr interessant, dort sind die ganzen Register wohl definiert.
und auch die Interrupt Vectoren Tabelle und Nummern wie sie im Speicher abgelegt werden.
So ähnlich (leider in C) sieht es bei meinem LPC1768 Controller von NXP (ebenfalls ein Cortex M3) auch aus.

Was ich etwas vermisse, vieleicht gibt es das ja, sind die Bit Records.
Also wie die Bits in einem Register verteilt sind. Quasi eine Varianten Record.
Hier erledigt der Compiler dann die Ausmaskierung bzw. die Bitschieberei bei Register Zugriffen:

Code: Alles auswählen

typedef unsigned int   U32;  /* 32 Bit without sign */

typedef volatile union
{
  struct
  {
    U32 Revision    :  4;   // [0..3] Revision nunber, the p value in the rnpn product revision identifier 0x0 = r2p0
    U32 PartNo      : 12;   // Part number of the processor: 0x23 = Cortex-M3
    U32 Constant    :  4;   // read as 0x0F
    U32 Variant     :  4;   // Variante number, the r value ist the rnpn product revision identifier
    U32 Implementer :  8;   // Implementer code: 0x41 = ARM
  } bits;
  U32 value;
} CPUID_TypeDef;

#define LPC_CPUID (*(CPUID_TypeDef *)(0xE000ED00))
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

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

Re: Arduino DUO läuft fast mit Lazarus.

Beitrag von Mathias »

Meinst du packedbit, so wie die Beispiele hier. https://wiki.freepascal.org/AVR_Embedde ... _output/de
Siehe 2. Hälfte.

In fpc gibt es zu jedem Controller eine passende, egal ob avr, arm, etc.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 572
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: Arduino DUO läuft fast mit Lazarus.

Beitrag von siro »

Das funktioniert ausgezeichnet, ich danke Dir Mathias:

Hier noch ein LINK dazu:
https://forum.lazarus.freepascal.org/in ... ic=42086.0

Code: Alles auswählen

Type T1Bit = 0..1;
     T2Bit = 0..3;
     T3Bit = 0..7;
     T4Bit = 0..15;
     T5Bit = 0..31;
     T6Bit = 0..63;
     T7Bit = 0..127;
     T8Bit = 0..255;
     T9Bit = 0..511;
     T10Bit = 0..1023;
     T11Bit = 0..2047;
     T12Bit = 0..4095;
//....usw.


Type CPUID_TypeDef = bitpacked record
  case boolean of
  true: (
    Revision    :  T4Bit;   // [0..3] Revision nunber, the p value in the rnpn product revision identifier 0x0 = r2p0
    PartNo      :  T12Bit;  // Part number of the processor: 0x23 = Cortex-M3
    Constant    :  T4Bit;   // read as 0x0F
    Variant     :  T4Bit;   // Variante number, the r value ist the rnpn product revision identifier
    Implementer :  T8Bit;   // Implementer code: 0x41 = ARM
    );
  false : ( value:UInt32);  // 32 Bit Wert
end;


// zum Testen habe ich eine Variable angelegt, sonst gibts nen Laufzeitfehler auf dem PC,
// hier darf ich ja nicht auf feste Adressen zugreifen.
var dummy:UInt32;
var LPC_CPUID : CPUID_TypeDef absolute dummy;    // var LPC_CPUID : CPUID_TypeDef absolute $E000ED00;

procedure TForm1.FormCreate(Sender: TObject);
begin
  LPC_CPUID.PartNo:=35;
  caption:=IntToStr(SizeOf(LPC_CPUID));   // ergibt 4, es werden 4 Bytes belegt
  caption:=IntToStr(LPC_CPUID.PartNo);    // ergibt 35, habe ich ja gesetzt
  caption:=IntToStr(LPC_CPUID.value);     // ergibt 560 weil (35 viermal links (Revision hat 4 Bits) schieben = 560)
end;                 
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

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

Re: Arduino DUO läuft fast mit Lazarus.

Beitrag von Mathias »

Ich habe den BitRecord gerade auf dem Desktop ausprobiert, scheint zu klappen.

Code: Alles auswählen

type
  T1Bit = 0..1;
  T2Bit = 0..3;
  T3Bit = 0..7;
  T4Bit = 0..15;
  TBitInt = bitpacked record
    case byte of
      0: (b3: T3Bit;
        b4: T4Bit;);
      1: (Value: UInt16);
  end;

var
  BitInt: TBitInt;

procedure TForm1.Button1Click(Sender: TObject);
begin
  BitInt.b4 := %1111;
  Repaint;
end;

procedure TForm1.FormPaint(Sender: TObject);
const
  r = 10;
var
  i: integer;
begin
  for i := 0 to 15 do begin
    if BitInt.Value and (1 shl i) = 1 shl i then begin
      Canvas.Brush.Color := clRed;
    end else begin
      Canvas.Brush.Color := clYellow;
    end;
    Canvas.Ellipse((16 - i) * r, r, (16 - i) * r + 10, r * 2);
  end;
end;
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

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

Re: Arduino DUO läuft fast mit Lazarus.

Beitrag von Mathias »

af0815 hat geschrieben:
Mi 4. Mai 2022, 19:47
Ein Watchdog soll sicherstellen, das das Programm wirklich läuft. Ansonsten kann man davon ausgehen, das da Programm hängt. Stell dir eine Temperatursteuerung vor, die aus einen blöden Grund hängt und voll ansteuert. Besser ein externer Prozess startet alles neu, damit der gewohnet Zustand wieder hergestellt werden kann.

Watchdogs sind nicht so selten, man muss nur lernen damit umzugehen.
Ich habe gerade gemerkt, das auch ein Atmega328 einen Watchdog hat.
Ich habe diesen gerade genutzt um einen einfachen Totmann zu realisieren.
Wen der Benutzer innert 4sec. keine Taste betätigt, geht der Alarm los. Welcher beim betätigen einer Taste zurück gesetzt wird.

Code: Alles auswählen

// Multi Function Shield - Watchdog Totmann

program Project1;

{$H-,J-,O-}

uses
  intrinsics;

type
  TPin = bitpacked record
    P0, P1, P2, P3, P4, P5, P6, P7: boolean;
  end;

var
  LED_DDR: TPin absolute DDRB;
  LED_port: TPin absolute PORTB;
  BeeperDDR: TPin absolute DDRD;
  BeeperPort: TPin absolute PORTD;
  Buttonport: TPin absolute PINC;

const
  WDP0 = 0;
  WDP1 = 1;
  WDP2 = 2;
  WDP3 = 5;


  // Der Interrupt, welcher ausgelöst wird, sobald eine Änderung bei den vorgebenen Tasten vorgenommen wird.
  // Überprüfen muss man selbst, was geändert wurde.
  // Auch wird der Watchdog zurückgesetzt wen eine Taste betätigt wird.

  procedure PC_Int1_Interrupt; public Name 'PCINT1_ISR'; interrupt;
  begin
    LED_port.P2 := Buttonport.P1;
    LED_port.P3 := Buttonport.P2;
    LED_port.P4 := Buttonport.P3;
    avr_wdr;
    BeeperPort.P3 := True;
  end;

  // Beeper gibt Alarm, wen keine Aktion an den Tasten vorliegt.

  procedure WDT_ISR_Interrupt; public Name 'WDT_ISR'; interrupt;
  begin
    BeeperPort.P3 := False;
  end;


begin
  // BP2 = D4, BP3 = D3, BP4 = D2
  // LED und Beeper schalten inventiert, da Rückleitung an VCC !

  // Interrupt aus
  avr_cli;

  // Interrupt für PortC aktivieren.
  PCICR := %010;

  // Port CP1, CP2, CP3 für Interrupt aktivieren.
  PCMSK1 := %00001110;

  // Watchdog aktivieren.
  WDTCSR := WDTCSR or (1 shl WDCE) or (1 shl WDE);
  WDTCSR := (1 shl WDIE) or (1 shl WDP3); // 4s / interrupt

  // Interrupt ein
  avr_sei;

  // LED-Port auf Output
  LED_DDR.P2 := True;
  LED_DDR.P3 := True;
  LED_DDR.P4 := True;

  // LED-Port auf Output
  BeeperDDR.P3 := True;

  // Beeper aus
  BeeperPort.P3 := True;

  // Alle LED aus
  LED_port.P2 := True;
  LED_port.P3 := True;
  LED_port.P4 := True;

  repeat
    // Mache irgend etwas
  until False;
end.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Antworten