mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-23 11:59:36 +02:00
* patch by Robert Roland to support the RaspberryPi 2 as a bare metal embedded target, resolves #35236
git-svn-id: trunk@44027 -
This commit is contained in:
parent
90a40ab9ca
commit
7b4292c94e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -10322,6 +10322,7 @@ rtl/embedded/arm/mk22f51212.pp svneol=native#text/pascal
|
|||||||
rtl/embedded/arm/mk64f12.pp svneol=native#text/pascal
|
rtl/embedded/arm/mk64f12.pp svneol=native#text/pascal
|
||||||
rtl/embedded/arm/nrf51.pp svneol=native#text/pascal
|
rtl/embedded/arm/nrf51.pp svneol=native#text/pascal
|
||||||
rtl/embedded/arm/nrf52.pp svneol=native#text/pascal
|
rtl/embedded/arm/nrf52.pp svneol=native#text/pascal
|
||||||
|
rtl/embedded/arm/raspi2.pp svneol=native#text/pascal
|
||||||
rtl/embedded/arm/sam3x8e.pp svneol=native#text/pascal
|
rtl/embedded/arm/sam3x8e.pp svneol=native#text/pascal
|
||||||
rtl/embedded/arm/sc32442b.pp svneol=native#text/pascal
|
rtl/embedded/arm/sc32442b.pp svneol=native#text/pascal
|
||||||
rtl/embedded/arm/stm32f0xx.pp svneol=native#text/plain
|
rtl/embedded/arm/stm32f0xx.pp svneol=native#text/plain
|
||||||
|
@ -508,6 +508,9 @@ Type
|
|||||||
ct_nrf52832_xxaa,
|
ct_nrf52832_xxaa,
|
||||||
ct_nrf52840_xxaa,
|
ct_nrf52840_xxaa,
|
||||||
|
|
||||||
|
{ Raspberry Pi 2 }
|
||||||
|
ct_raspi2,
|
||||||
|
|
||||||
// generic Thumb2 target
|
// generic Thumb2 target
|
||||||
ct_thumb2bare
|
ct_thumb2bare
|
||||||
);
|
);
|
||||||
@ -1025,6 +1028,9 @@ Const
|
|||||||
(controllertypestr:'NRF52832_XXAA'; controllerunitstr:'NRF52'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
|
(controllertypestr:'NRF52832_XXAA'; controllerunitstr:'NRF52'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
|
||||||
(controllertypestr:'NRF52840_XXAA'; controllerunitstr:'NRF52'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
|
(controllertypestr:'NRF52840_XXAA'; controllerunitstr:'NRF52'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
|
||||||
|
|
||||||
|
{ Raspberry Pi 2 }
|
||||||
|
(controllertypestr:'RASPI2'; controllerunitstr:'RASPI2'; cputype:cpu_armv7a; fputype:fpu_vfpv4; flashbase:$00000000; flashsize:$00000000; srambase:$00008000; sramsize:$10000000),
|
||||||
|
|
||||||
{ Bare bones }
|
{ Bare bones }
|
||||||
(controllertypestr:'THUMB2_BARE'; controllerunitstr:'THUMB2_BARE'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000; flashsize:$00002000; srambase:$20000000; sramsize:$00000400)
|
(controllertypestr:'THUMB2_BARE'; controllerunitstr:'THUMB2_BARE'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000; flashsize:$00002000; srambase:$20000000; sramsize:$00000400)
|
||||||
);
|
);
|
||||||
|
@ -618,6 +618,10 @@ begin
|
|||||||
ct_nrf52840_xxaa,
|
ct_nrf52840_xxaa,
|
||||||
|
|
||||||
ct_sc32442b,
|
ct_sc32442b,
|
||||||
|
|
||||||
|
{ Raspberry Pi 2 }
|
||||||
|
ct_raspi2,
|
||||||
|
|
||||||
ct_thumb2bare:
|
ct_thumb2bare:
|
||||||
begin
|
begin
|
||||||
with embedded_controllers[current_settings.controllertype] do
|
with embedded_controllers[current_settings.controllertype] do
|
||||||
|
@ -376,7 +376,7 @@ CPU_UNITS=lpc8xx lpc11xx lpc122x stm32f0xx nrf51 cortexm0
|
|||||||
CPU_UNITS_DEFINED=1
|
CPU_UNITS_DEFINED=1
|
||||||
endif
|
endif
|
||||||
ifeq ($(SUBARCH),armv7a)
|
ifeq ($(SUBARCH),armv7a)
|
||||||
CPU_UNITS=allwinner_a20
|
CPU_UNITS=allwinner_a20 raspi2
|
||||||
CPU_UNITS_DEFINED=1
|
CPU_UNITS_DEFINED=1
|
||||||
endif
|
endif
|
||||||
ifeq ($(CPU_UNITS_DEFINED),)
|
ifeq ($(CPU_UNITS_DEFINED),)
|
||||||
|
@ -91,7 +91,7 @@ CPU_UNITS=lpc8xx lpc11xx lpc122x stm32f0xx nrf51 cortexm0
|
|||||||
CPU_UNITS_DEFINED=1
|
CPU_UNITS_DEFINED=1
|
||||||
endif
|
endif
|
||||||
ifeq ($(SUBARCH),armv7a)
|
ifeq ($(SUBARCH),armv7a)
|
||||||
CPU_UNITS=allwinner_a20
|
CPU_UNITS=allwinner_a20 raspi2
|
||||||
CPU_UNITS_DEFINED=1
|
CPU_UNITS_DEFINED=1
|
||||||
endif
|
endif
|
||||||
ifeq ($(CPU_UNITS_DEFINED),)
|
ifeq ($(CPU_UNITS_DEFINED),)
|
||||||
|
204
rtl/embedded/arm/raspi2.pp
Normal file
204
rtl/embedded/arm/raspi2.pp
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
unit raspi2;
|
||||||
|
|
||||||
|
{$goto on}
|
||||||
|
{$INLINE ON}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
type
|
||||||
|
TBitvector32 = bitpacked array[0..31] of 0..1;
|
||||||
|
|
||||||
|
const
|
||||||
|
PeripheralBase = $3F000000;
|
||||||
|
|
||||||
|
GPFSEL1 = PeripheralBase + $00200004;
|
||||||
|
GPSET0 = PeripheralBase + $0020001C;
|
||||||
|
GPCLR0 = PeripheralBase + $00200028;
|
||||||
|
GPPUD = PeripheralBase + $00200094;
|
||||||
|
GPPUDCLK0 = PeripheralBase + $00200098;
|
||||||
|
|
||||||
|
AUX_ENABLES = PeripheralBase + $00215004;
|
||||||
|
AUX_MU_IO_REG = PeripheralBase + $00215040;
|
||||||
|
AUX_MU_IER_REG = PeripheralBase + $00215044;
|
||||||
|
AUX_MU_IIR_REG = PeripheralBase + $00215048;
|
||||||
|
AUX_MU_LCR_REG = PeripheralBase + $0021504C;
|
||||||
|
AUX_MU_MCR_REG = PeripheralBase + $00215050;
|
||||||
|
AUX_MU_LSR_REG = PeripheralBase + $00215054;
|
||||||
|
AUX_MU_MSR_REG = PeripheralBase + $00215058;
|
||||||
|
AUX_MU_SCRATCH = PeripheralBase + $0021505C;
|
||||||
|
AUX_MU_CNTL_REG = PeripheralBase + $00215060;
|
||||||
|
AUX_MU_STAT_REG = PeripheralBase + $00215064;
|
||||||
|
AUX_MU_BAUD_REG = PeripheralBase + $00215068;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
consoleio;
|
||||||
|
|
||||||
|
procedure _FPC_haltproc; assembler; nostackframe; public name '_haltproc';
|
||||||
|
asm
|
||||||
|
.Lhalt:
|
||||||
|
wfi
|
||||||
|
b .Lhalt
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DUMMY(Count: DWord);
|
||||||
|
var
|
||||||
|
i : DWord;
|
||||||
|
begin
|
||||||
|
for i := 0 to Count do
|
||||||
|
begin
|
||||||
|
asm
|
||||||
|
nop
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure PUT32(Address: DWord; Value: DWord); inline;
|
||||||
|
VAR
|
||||||
|
p: ^DWord;
|
||||||
|
begin
|
||||||
|
p := POINTER (Address);
|
||||||
|
p^ := Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GET32(Address: DWord) : DWord; inline;
|
||||||
|
VAR
|
||||||
|
p: ^DWord;
|
||||||
|
begin
|
||||||
|
p := POINTER (Address);
|
||||||
|
GET32 := p^;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function UARTLCR(): DWord;
|
||||||
|
begin
|
||||||
|
UARTLCR := GET32(AUX_MU_LCR_REG);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure UARTPuts(C: Char);
|
||||||
|
begin
|
||||||
|
while True do
|
||||||
|
begin
|
||||||
|
if (GET32(AUX_MU_LSR_REG) and $20) > 0 then break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PUT32(AUX_MU_IO_REG, DWord(C));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function UARTGet(): Char;
|
||||||
|
begin
|
||||||
|
while True do
|
||||||
|
begin
|
||||||
|
if (GET32(AUX_MU_LSR_REG) and $01) > 0 then break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
UARTGet := Char(GET32(AUX_MU_IO_REG) and $FF);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure UARTFlush();
|
||||||
|
begin
|
||||||
|
while True do
|
||||||
|
begin
|
||||||
|
if (GET32(AUX_MU_LSR_REG) and $100) > 0 then break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function RaspiWrite(ACh: char; AUserData: pointer): boolean;
|
||||||
|
begin
|
||||||
|
UARTPuts(ACh);
|
||||||
|
|
||||||
|
RaspiWrite := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function RaspiRead(var ACh: char; AUserData: pointer): boolean;
|
||||||
|
begin
|
||||||
|
if (GET32(AUX_MU_LSR_REG) and $01) > 0 then
|
||||||
|
begin
|
||||||
|
ACh := UARTGet();
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
ACh := #0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
RaspiRead := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure UARTInit; public name 'UARTInit';
|
||||||
|
var
|
||||||
|
ra: dword;
|
||||||
|
begin
|
||||||
|
PUT32(AUX_ENABLES, 1);
|
||||||
|
PUT32(AUX_MU_IER_REG, 0);
|
||||||
|
PUT32(AUX_MU_CNTL_REG, 0);
|
||||||
|
PUT32(AUX_MU_LCR_REG, 3);
|
||||||
|
PUT32(AUX_MU_MCR_REG, 0);
|
||||||
|
PUT32(AUX_MU_IER_REG, 0);
|
||||||
|
PUT32(AUX_MU_IIR_REG, $C6);
|
||||||
|
PUT32(AUX_MU_BAUD_REG, 270);
|
||||||
|
|
||||||
|
ra := GET32(GPFSEL1);
|
||||||
|
ra := ra AND (not (7 shl 12)); // gpio14
|
||||||
|
ra := ra OR (2 shl 12); // alt5
|
||||||
|
ra := ra AND (not (7 shl 15)); // gpio15
|
||||||
|
ra := ra OR (2 shl 15); // alt5
|
||||||
|
|
||||||
|
PUT32(GPFSEL1, ra);
|
||||||
|
PUT32(GPPUD, 0);
|
||||||
|
|
||||||
|
Dummy(500);
|
||||||
|
|
||||||
|
PUT32(GPPUDCLK0, ((1 shl 14) OR (1 shl 15)));
|
||||||
|
|
||||||
|
Dummy(500);
|
||||||
|
|
||||||
|
PUT32(GPPUDCLK0, 0);
|
||||||
|
PUT32(AUX_MU_CNTL_REG, 3);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ifndef CUSTOM_ENTRY}
|
||||||
|
procedure PASCALMAIN; external name 'PASCALMAIN';
|
||||||
|
|
||||||
|
var
|
||||||
|
_stack_top: record end; external name '_stack_top';
|
||||||
|
|
||||||
|
{ This start makes sure we only execute on core 0 - the others will halt }
|
||||||
|
procedure _FPC_start; assembler; nostackframe;
|
||||||
|
label
|
||||||
|
_start;
|
||||||
|
asm
|
||||||
|
.init
|
||||||
|
.align 16
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
// enable fpu
|
||||||
|
.long 0xee110f50 // mrc p15, 0, r0, c1, c0, 2
|
||||||
|
orr r0, r0, #0x300000 // single precision
|
||||||
|
orr r0, r0, #0xC00000 // double precision
|
||||||
|
.long 0xee010f50 // mcr p15, 0, r0, c1, c0, 2
|
||||||
|
mov r0, #0x40000000
|
||||||
|
.long 0xeee80a10 // fmxr fpexc, r0
|
||||||
|
|
||||||
|
.long 0xee100fb0 // mrc p15,0,r0,c0,c0,5 - find the core ID
|
||||||
|
mov r1, #0xFF
|
||||||
|
ands r1, r1, r0
|
||||||
|
bne _FPC_haltproc
|
||||||
|
|
||||||
|
ldr r0, .L_stack_top
|
||||||
|
mov sp, r0
|
||||||
|
|
||||||
|
bl UARTInit
|
||||||
|
bl PASCALMAIN
|
||||||
|
bl _FPC_haltproc
|
||||||
|
.L_stack_top:
|
||||||
|
.long _stack_top
|
||||||
|
.text
|
||||||
|
end;
|
||||||
|
{$endif CUSTOM_ENTRY}
|
||||||
|
|
||||||
|
begin
|
||||||
|
OpenIO(Input, @RaspiWrite, @RaspiRead, fmInput, nil);
|
||||||
|
OpenIO(Output, @RaspiWrite, @RaspiRead, fmOutput, nil);
|
||||||
|
OpenIO(ErrOutput, @RaspiWrite, @RaspiRead, fmOutput, nil);
|
||||||
|
OpenIO(StdOut, @RaspiWrite, @RaspiRead, fmOutput, nil);
|
||||||
|
OpenIO(StdErr, @RaspiWrite, @RaspiRead, fmOutput, nil);
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user