123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- {$IFNDEF FPC_DOTTEDUNITS}
- unit raspi2;
- {$ENDIF FPC_DOTTEDUNITS}
- {$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
- {$IFDEF FPC_DOTTEDUNITS}
- uses
- EmbeddedApi.ConsoleIO;
- {$ELSE FPC_DOTTEDUNITS}
- uses
- consoleio;
- {$ENDIF FPC_DOTTEDUNITS}
- 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: AnsiChar);
- 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(): AnsiChar;
- begin
- while True do
- begin
- if (GET32(AUX_MU_LSR_REG) and $01) > 0 then break;
- end;
- UARTGet := AnsiChar(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: AnsiChar; AUserData: pointer): boolean;
- begin
- UARTPuts(ACh);
- RaspiWrite := true;
- end;
- function RaspiRead(var ACh: AnsiChar; 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.
|