Difference between revisions of "Unit PlatformRPi4"
(8 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
---- | ---- | ||
− | '''Ultibo Platform | + | '''Ultibo Platform Interface unit for Raspberry Pi 4''' |
Note: The RPi4B has the Activity LED connected to GPIO Pin 42 (Power LED is only accessible via the GPIO expander driver) | Note: The RPi4B has the Activity LED connected to GPIO Pin 42 (Power LED is only accessible via the GPIO expander driver) | ||
Line 223: | Line 223: | ||
| | | | ||
|- | |- | ||
− | |colspan="2"|<code>RPI4_FIRMWARE_FILES = 'start4.elf,fixup4.dat | + | |colspan="2"|<code>RPI4_FIRMWARE_FILES = 'start4.elf,fixup4.dat,armstub32-rpi4.bin,armstub64-rpi4.bin';</code> |
+ | |- | ||
+ | |colspan="2"|<code>RPI4_DTB_FILES = 'bcm2711-rpi-4-b.dtb,bcm2711-rpi-400.dtb,bcm2711-rpi-cm4.dtb,bcm2711-rpi-cm4s.dtb';</code> | ||
|- | |- | ||
|} | |} | ||
Line 312: | Line 314: | ||
---- | ---- | ||
− | '' | + | |
+ | '''RPi4 framebuffer''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PRPi4Framebuffer = ^TRPi4Framebuffer;</code> | ||
+ | |||
+ | <code>TRPi4Framebuffer = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''Framebuffer Properties'' | ||
+ | |- | ||
+ | | <code>Framebuffer:TFramebufferDevice;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |colspan="2"|''RPi4 Properties'' | ||
+ | |- | ||
+ | | <code>MultiDisplay:LongBool;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>DisplayNum:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>DisplaySettings:TDisplaySettings;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Public variables === | === Public variables === | ||
Line 748: | Line 778: | ||
| Data = first 28 bits, Channel = last 4 bits | | Data = first 28 bits, Channel = last 4 bits | ||
Data pointer must be 16 byte aligned to allow for the 4 bit channel number | Data pointer must be 16 byte aligned to allow for the 4 bit channel number | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function RPi4MailboxPropertyTag(Tag:LongWord; Data:Pointer; Size:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Request a property tag (Get/Set) from the mailbox property channel</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Data | ||
+ | | Data does not need to include mailbox property channel header or footer. Data pointer does not need any specific alignment or caching attributes. | ||
+ | |- | ||
+ | ! Size | ||
+ | | Size must be a multiple of 4 bytes. Size must include the size of the request and response which use the same buffer. | ||
|- | |- | ||
|} | |} | ||
Line 1,091: | Line 1,136: | ||
<pre style="border: 0; padding-bottom:0px;">function RPi4BoardGetMACAddress:String;</pre> | <pre style="border: 0; padding-bottom:0px;">function RPi4BoardGetMACAddress:String;</pre> | ||
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the Board MAC Address from the Mailbox property tags channel</div> | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the Board MAC Address from the Mailbox property tags channel</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function RPi4ChipGetRevision:LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the Chip Revision from the revision register</div> | ||
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
{| class="wikitable" style="font-size: 14px; background: white;" | {| class="wikitable" style="font-size: 14px; background: white;" | ||
Line 1,775: | Line 1,832: | ||
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferTestPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;</pre> | <pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferTestPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;</pre> | ||
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Test Framebuffer Palette from the Mailbox property tags channel</div> | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Test Framebuffer Palette from the Mailbox property tags channel</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferGetLayer(var Layer:LongInt):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get Framebuffer Layer from the Mailbox property tags channel</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferSetLayer(var Layer:LongInt):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set Framebuffer Layer from the Mailbox property tags channel</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferTestLayer(var Layer:LongInt):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Test Framebuffer Layer from the Mailbox property tags channel</div> | ||
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
{| class="wikitable" style="font-size: 14px; background: white;" | {| class="wikitable" style="font-size: 14px; background: white;" | ||
Line 2,205: | Line 2,298: | ||
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferDeviceSetBacklight(Framebuffer:PFramebufferDevice; Brightness:LongWord):LongWord;</pre> | <pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferDeviceSetBacklight(Framebuffer:PFramebufferDevice; Brightness:LongWord):LongWord;</pre> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div> | ||
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
Line 2,298: | Line 2,379: | ||
! Note | ! Note | ||
| None documented | | None documented | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure RPi4BootOutput(Value:LongWord);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Output characters to UART0 without dependency on any other RTL setup</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | This function is primarily intended for testing QEMU boot because it doesn't initialize the UART and won't work on real hardware. | ||
+ | Based on hexstrings() function by dwelch67 (https://github.com/dwelch67) | ||
|- | |- | ||
|} | |} |
Latest revision as of 05:08, 23 November 2022
Return to Unit Reference
Contents
[hide]Description
Ultibo Platform Interface unit for Raspberry Pi 4
Note: The RPi4B has the Activity LED connected to GPIO Pin 42 (Power LED is only accessible via the GPIO expander driver)
Detecting the GIC or legacy interrupt controller
The Raspberry Pi 4 contains a new GIC interrupt controller which includes modern features like the ability to service interrupts on all available cores, a full set of software generated processor to processor interrupts and complete FIQ handling for all interrupt sources.
The Pi 4 also retains and expands the legacy interrupt controller used on earlier Pi models with support for routing interrupts to any core and FIQ handling for all interrupt sources.
The documentation at https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md states that the setting enable_gic=0 or 1 can be used to select between the legacy and GIC interrupt controllers and that the GIC (enable_gic=1) is the default.
Testing however shows this is not completely correct, if no config.txt file exists and no device tree DTB files are present then the current firmware appears to enable the legacy interrupt controller by default.
If device tree DTB files containing a compatible GIC node are available on the SD card during boot the firmware will enable the GIC, this appears to happen regardless of the setting in config.txt and a value of enable_gic=0 will be ignored in favour of the device tree setting.
If the legacy interrupt controller is enabled and Ultibo configures the GIC controller during boot it will receive no interrupts and appear to hang (four color screen).
While it might be possible to read the SD card during boot, check for a config.txt and parse it to determine the value of the enable_gic setting, to be fully functional this process would also need to parse the device tree information (if available) and check for a compatible GIC node. Even then that doesn't account for booting from USB, network or some other source and all of that would have to happen very early in the boot sequence to be usable.
To make matters worse there doesn't appear to be a documented way to detect which interrupt controller is enabled by reading a register value, the GIC even behaves as though it is working when the legacy controller is enabled but no interrupts are received.
To ensure a level of reliability regardless of what firmware and files and configuration settings are present Ultibo implements drivers for both the GIC and legacy interrupt controllers and includes a detection mechanism during early stage boot.
In simple terms the boot process configures the GIC and then installs an interrupt handler for the generic virtual timer and configures the timer to fire in 1ms before enabling interrupts. It then waits 2ms and disables interrupts, unconfigures the timer and deregisters the interrupt handler.
If the test worked the local variable GICAvailable will have been set by the handler to RPI4_GIC_AVAILABLE, if not the variable will remain at RPI4_GIC_UNAVAILABLE and the boot process will proceed to configure the legacy interrupt controller for use.
This is not an ideal mechanism and could potentially fail for other reasons (although it is carefully constructed to avoid many potential failures) but at present is the best option for allowing the boot process to succeed regardless of the firmware behavior.
Constants
RPI4_VCIO_*
RPI4_VCBUS_*
RPI4_SECURE_*
RPI4_STARTUP_*
RPI4_PAGE_DIRECTORY_*
RPI4_PAGE_TABLE_*
RPI4_VECTOR_TABLE_*
RPI4_CPU_*
RPI4_SWI_*
RPI4_GIC_*
RPI4_CORE_TIMER_*
RPI4_KERNEL_*
RPI4_GPIO_ACTLED_*
RPI4_MAILBOX_TIMEOUT_*
RPI4_LOCAL_MAILBOX_*
RPI4_FRAMEBUFFER_*
Type definitions
RPi4 framebuffer
Public variables
RPi4 specific Ultibo variables
RPi4Initialized:Boolean;
|
RPi4CNTVOFFLow:LongWord = 0;
|
The low 32 bits of the Virtual Counter Offset register at boot time (CPU0 only) (Set by Startup) Must be initialized to remain in .data or else rewritten to zero with .bss |
RPi4CNTVOFFHigh:LongWord = 0;
|
The high 32 bits of the Virtual Counter Offset register at boot time (CPU0 only) (Set by Startup) Must be initialized to remain in .data or else rewritten to zero with .bss |
Timer register
TimerRegisters:PBCM2838SystemTimerRegisters;
|
Mailbox register
Mailbox0Registers:PBCM2838Mailbox0Registers;
|
Mailbox1Registers:PBCM2838Mailbox1Registers;
|
Interrupt device
GICDevice:PGICDevice;
|
GICAvailable:LongWord = RPI4_GIC_AVAILABLE;
|
The status of the GIC interrupt controller, determined during boot. |
System call
SystemCallEntries:array[0..RPI4_SWI_COUNT - 1] of TSystemCallEntry;
|
Watchdog register
WatchdogRegisters:PBCM2838PMWatchdogRegisters;
|
ARM local register
ARMLocalRegisters:PBCM2838ARMLocalRegisters;
|
Virtual GPIO
VirtualGPIOBuffer:TBCM2838VirtualGPIOBuffer;
|
Function declarations
Initialization functions
RPi4 platform functions
procedure RPi4PageTableInit;
procedure RPi4PageTableInitLegacy;
function RPi4MailboxReceive(Mailbox,Channel:LongWord):LongWord;
procedure RPi4MailboxSend(Mailbox,Channel,Data:LongWord);
function RPi4MailboxCall(Mailbox,Channel,Data:LongWord; var Response:LongWord):LongWord;
function RPi4MailboxCallEx(Mailbox,Channel,Data:LongWord; var Response:LongWord; Timeout:LongWord):LongWord;
function RPi4MailboxPropertyCall(Mailbox,Channel:LongWord; Data:Pointer; var Response:LongWord):LongWord;
function RPi4MailboxPropertyCallEx(Mailbox,Channel:LongWord; Data:Pointer; var Response:LongWord; Timeout:LongWord):LongWord;
function RPi4MailboxPropertyTag(Tag:LongWord; Data:Pointer; Size:LongWord):LongWord;
function RPi4RequestExIRQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
function RPi4ReleaseExIRQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
function RPi4RequestExFIQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
function RPi4ReleaseExFIQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
function RPi4RequestIPI(CPUID,Number:LongWord; Handler:TIPIHandler; Parameter:Pointer):LongWord;
function RPi4ReleaseIPI(CPUID,Number:LongWord; Handler:TIPIHandler; Parameter:Pointer):LongWord;
function RPi4RegisterInterrupt(Number,Mask,Priority,Flags:LongWord; Handler:TSharedInterruptHandler; Parameter:Pointer):LongWord;
function RPi4DeregisterInterrupt(Number,Mask,Priority,Flags:LongWord; Handler:TSharedInterruptHandler; Parameter:Pointer):LongWord;
function RPi4RegisterSystemCallEx(CPUID,Number:LongWord; Handler:TSystemCallHandler; HandlerEx:TSystemCallExHandler):LongWord;
function RPi4DeregisterSystemCallEx(CPUID,Number:LongWord; Handler:TSystemCallHandler; HandlerEx:TSystemCallExHandler):LongWord;
function RPi4GetInterruptEntry(Number,Instance:LongWord; var Interrupt:TInterruptEntry):LongWord;
function RPi4GetLocalInterruptEntry(CPUID,Number,Instance:LongWord; var Interrupt:TInterruptEntry):LongWord;
function RPi4GetSoftwareInterruptEntry(CPUID,Number,Instance:LongWord; var Interrupt:TInterruptEntry):LongWord;
function RPi4GetSystemCallEntry(Number:LongWord):TSystemCallEntry;
function RPi4SystemGetCommandLine:String;
function RPi4CPUGetMemory(var Address:PtrUInt; var Length:UInt64):LongWord;
function RPi4GPUGetMemory(var Address:PtrUInt; var Length:UInt64):LongWord;
function RPi4BoardGetModel:LongWord;
function RPi4BoardGetSerial:Int64;
function RPi4BoardGetRevision:LongWord;
function RPi4BoardGetMACAddress:String;
function RPi4ChipGetRevision:LongWord;
function RPi4FirmwareGetRevision:LongWord;
function RPi4FirmwareGetThrottled:LongWord;
function RPi4PowerGetWait(PowerId:LongWord):LongWord;
function RPi4PowerGetState(PowerId:LongWord):LongWord;
function RPi4PowerSetState(PowerId,State:LongWord; Wait:Boolean):LongWord;
function RPi4ClockGetCount:LongWord;
function RPi4ClockGetRate(ClockId:LongWord):LongWord;
function RPi4ClockSetRate(ClockId,Rate:LongWord; Turbo:Boolean):LongWord;
function RPi4ClockGetState(ClockId:LongWord):LongWord;
function RPi4ClockSetState(ClockId,State:LongWord):LongWord;
function RPi4ClockGetMinRate(ClockId:LongWord):LongWord;
function RPi4ClockGetMaxRate(ClockId:LongWord):LongWord;
function RPi4TurboGetState(TurboId:LongWord):LongWord;
function RPi4TurboSetState(TurboId,State:LongWord):LongWord;
function RPi4VoltageGetValue(VoltageId:LongWord):LongWord;
function RPi4VoltageSetValue(VoltageId,Value:LongWord):LongWord;
function RPi4VoltageGetMinValue(VoltageId:LongWord):LongWord;
function RPi4VoltageGetMaxValue(VoltageId:LongWord):LongWord;
function RPi4TemperatureGetCurrent(TemperatureId:LongWord):LongWord;
function RPi4TemperatureGetMaximum(TemperatureId:LongWord):LongWord;
function RPi4GPUMemoryAllocate(Length,Alignment,Flags:LongWord):THandle;
function RPi4GPUMemoryRelease(Handle:THandle):LongWord;
function RPi4GPUMemoryLock(Handle:THandle):LongWord;
function RPi4GPUMemoryUnlock(Handle:THandle):LongWord;
function RPi4GPUExecuteCode(Address:Pointer; R0,R1,R2,R3,R4,R5:LongWord):LongWord;
function RPi4DispmanxHandleGet(Resource:THandle):THandle;
function RPi4EDIDBlockGet(Block:LongWord; Buffer:Pointer; Length:LongWord):LongWord;
function RPi4FramebufferAllocate(Alignment:LongWord; var Address,Length:LongWord):LongWord;
function RPi4FramebufferRelease:LongWord;
function RPi4FramebufferSetState(State:LongWord):LongWord;
function RPi4FramebufferGetDimensions(var Width,Height,Top,Bottom,Left,Right:LongWord):LongWord;
function RPi4FramebufferGetPhysical(var Width,Height:LongWord):LongWord;
function RPi4FramebufferSetPhysical(var Width,Height:LongWord):LongWord;
function RPi4FramebufferTestPhysical(var Width,Height:LongWord):LongWord;
function RPi4FramebufferGetVirtual(var Width,Height:LongWord):LongWord;
function RPi4FramebufferSetVirtual(var Width,Height:LongWord):LongWord;
function RPi4FramebufferTestVirtual(var Width,Height:LongWord):LongWord;
function RPi4FramebufferGetDepth(var Depth:LongWord):LongWord;
function RPi4FramebufferSetDepth(var Depth:LongWord):LongWord;
function RPi4FramebufferTestDepth(var Depth:LongWord):LongWord;
function RPi4FramebufferGetPixelOrder(var Order:LongWord):LongWord;
function RPi4FramebufferSetPixelOrder(var Order:LongWord):LongWord;
function RPi4FramebufferTestPixelOrder(var Order:LongWord):LongWord;
function RPi4FramebufferGetAlphaMode(var Mode:LongWord):LongWord;
function RPi4FramebufferSetAlphaMode(var Mode:LongWord):LongWord;
function RPi4FramebufferTestAlphaMode(var Mode:LongWord):LongWord;
function RPi4FramebufferGetPitch:LongWord;
function RPi4FramebufferGetOffset(var X,Y:LongWord):LongWord;
function RPi4FramebufferSetOffset(var X,Y:LongWord):LongWord;
function RPi4FramebufferTestOffset(var X,Y:LongWord):LongWord;
function RPi4FramebufferGetOverscan(var Top,Bottom,Left,Right:LongWord):LongWord;
function RPi4FramebufferSetOverscan(var Top,Bottom,Left,Right:LongWord):LongWord;
function RPi4FramebufferTestOverscan(var Top,Bottom,Left,Right:LongWord):LongWord;
function RPi4FramebufferGetPalette(Buffer:Pointer;Length:LongWord):LongWord;
function RPi4FramebufferSetPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;
function RPi4FramebufferTestPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;
function RPi4FramebufferGetLayer(var Layer:LongInt):LongWord;
function RPi4FramebufferSetLayer(var Layer:LongInt):LongWord;
function RPi4FramebufferTestLayer(var Layer:LongInt):LongWord;
function RPi4FramebufferTestVsync:LongWord;
function RPi4FramebufferSetVsync:LongWord;
function RPi4FramebufferSetBacklight(Brightness:LongWord):LongWord;
function RPi4FramebufferGetNumDisplays(var NumDisplays:LongWord):LongWord;
function RPi4FramebufferGetDisplayId(DisplayNum:LongWord):LongWord;
function RPi4FramebufferSetDisplayNum(DisplayNum:LongWord):LongWord;
function RPi4FramebufferGetDisplaySettings(DisplayNum:LongWord; var DisplaySettings:TDisplaySettings):LongWord;
function RPi4FramebufferDisplayIdToName(DisplayId:LongWord):String;
function RPi4TouchGetBuffer(var Address:PtrUInt):LongWord;
function RPi4TouchSetBuffer(Address:PtrUInt):LongWord;
function RPi4VirtualGPIOGetBuffer(var Address:PtrUInt):LongWord;
function RPi4VirtualGPIOSetBuffer(Address:PtrUInt):LongWord;
function RPi4CursorSetDefault:LongWord;
function RPi4CursorSetInfo(Width,Height,HotspotX,HotspotY:LongWord; Pixels:Pointer; Length:LongWord):LongWord;
function RPi4CursorSetState(Enabled:Boolean; X,Y:LongWord; Relative:Boolean):LongWord;
function RPi4DMAGetChannels:LongWord;
function RPi4VirtualGPIOOutputSet(Pin,Level:LongWord):LongWord;
function RPi4VirtualGPIOFunctionSelect(Pin,Mode:LongWord):LongWord;
RPi4 thread functions
procedure RPi4SchedulerInit;
procedure RPi4SchedulerStart(CPUID:LongWord);
RPi4 SWI functions
function RPi4DispatchSWI(CPUID:LongWord; Thread:TThreadHandle; Request:PSystemCallRequest):TThreadHandle;
RPi4 clock functions
procedure RPi4ClockInterrupt(Parameter:Pointer);
procedure RPi4ClockUpdate(Cycles:LongWord; var Last:LongWord);
RPi4 scheduler functions
function RPi4SchedulerInterrupt(CPUID:LongWord; Thread:TThreadHandle; Parameter:Pointer):TThreadHandle;
procedure RPi4SchedulerUpdate(Cycles:LongWord; var Last:LongWord);
procedure RPi4SchedulerSystemCall(Request:PSystemCallRequest);
RPi4 framebuffer functions
function RPi4FramebufferDeviceAllocate(Framebuffer:PFramebufferDevice; Properties:PFramebufferProperties):LongWord;
function RPi4FramebufferDeviceAllocateAlt(Framebuffer:PFramebufferDevice; Properties:PFramebufferProperties):LongWord;
function RPi4FramebufferDeviceRelease(Framebuffer:PFramebufferDevice):LongWord;
function RPi4FramebufferDeviceBlank(Framebuffer:PFramebufferDevice; Blank:Boolean):LongWord;
function RPi4FramebufferDeviceCommit(Framebuffer:PFramebufferDevice; Address:PtrUInt; Size,Flags:LongWord):LongWord;
function RPi4FramebufferDeviceSetBacklight(Framebuffer:PFramebufferDevice; Brightness:LongWord):LongWord;
RPi4 helper functions
procedure RPi4BootBlink;
procedure RPi4BootOutput(Value:LongWord);
procedure RPi4BootConsoleWriteEx(const Value:String; X,Y:LongWord);
function RPi4ConvertPowerIdRequest(PowerId:LongWord):LongWord;
function RPi4ConvertPowerStateRequest(PowerState:LongWord):LongWord;
function RPi4ConvertPowerStateResponse(PowerState:LongWord):LongWord;
function RPi4ConvertClockIdRequest(ClockId:LongWord):LongWord;
function RPi4ConvertClockStateRequest(ClockState:LongWord):LongWord;
function RPi4ConvertClockStateResponse(ClockState:LongWord):LongWord;
function RPi4ConvertVoltageIdRequest(VoltageId:LongWord):LongWord;
function RPi4ConvertTemperatureIdRequest(TemperatureId:LongWord):LongWord;
Return to Unit Reference