diff --git a/.gitattributes b/.gitattributes index 3e616523d8..5cb7609bbd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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/nrf51.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/sc32442b.pp svneol=native#text/pascal rtl/embedded/arm/stm32f0xx.pp svneol=native#text/plain diff --git a/compiler/arm/cpuinfo.pas b/compiler/arm/cpuinfo.pas index 845496b5b7..2c5127b809 100644 --- a/compiler/arm/cpuinfo.pas +++ b/compiler/arm/cpuinfo.pas @@ -508,6 +508,9 @@ Type ct_nrf52832_xxaa, ct_nrf52840_xxaa, + { Raspberry Pi 2 } + ct_raspi2, + // generic Thumb2 target 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:'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 } (controllertypestr:'THUMB2_BARE'; controllerunitstr:'THUMB2_BARE'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000; flashsize:$00002000; srambase:$20000000; sramsize:$00000400) ); diff --git a/compiler/systems/t_embed.pas b/compiler/systems/t_embed.pas index ba59e63c8b..f844c5321a 100644 --- a/compiler/systems/t_embed.pas +++ b/compiler/systems/t_embed.pas @@ -618,6 +618,10 @@ begin ct_nrf52840_xxaa, ct_sc32442b, + + { Raspberry Pi 2 } + ct_raspi2, + ct_thumb2bare: begin with embedded_controllers[current_settings.controllertype] do diff --git a/rtl/embedded/Makefile b/rtl/embedded/Makefile index 8432d8b02d..d78f734507 100644 --- a/rtl/embedded/Makefile +++ b/rtl/embedded/Makefile @@ -376,7 +376,7 @@ CPU_UNITS=lpc8xx lpc11xx lpc122x stm32f0xx nrf51 cortexm0 CPU_UNITS_DEFINED=1 endif ifeq ($(SUBARCH),armv7a) -CPU_UNITS=allwinner_a20 +CPU_UNITS=allwinner_a20 raspi2 CPU_UNITS_DEFINED=1 endif ifeq ($(CPU_UNITS_DEFINED),) diff --git a/rtl/embedded/Makefile.fpc b/rtl/embedded/Makefile.fpc index e27aea778f..3033ebe497 100644 --- a/rtl/embedded/Makefile.fpc +++ b/rtl/embedded/Makefile.fpc @@ -91,7 +91,7 @@ CPU_UNITS=lpc8xx lpc11xx lpc122x stm32f0xx nrf51 cortexm0 CPU_UNITS_DEFINED=1 endif ifeq ($(SUBARCH),armv7a) -CPU_UNITS=allwinner_a20 +CPU_UNITS=allwinner_a20 raspi2 CPU_UNITS_DEFINED=1 endif ifeq ($(CPU_UNITS_DEFINED),) diff --git a/rtl/embedded/arm/raspi2.pp b/rtl/embedded/arm/raspi2.pp new file mode 100644 index 0000000000..f63cdd2169 --- /dev/null +++ b/rtl/embedded/arm/raspi2.pp @@ -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. \ No newline at end of file