Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c7bcc1911 | ||
|
|
e09c9b5595 | ||
|
|
9476bb0c8a | ||
|
|
8f7db8507b | ||
|
|
452203b7b4 | ||
|
|
76c419336e | ||
|
|
2ad0ae8420 | ||
|
|
c0c199bfe6 | ||
|
|
7ec3bcb9b9 | ||
|
|
4bd0a2dfbf | ||
|
|
431e5bc8f4 | ||
|
|
8169d93a9c | ||
|
|
547251dbd0 | ||
|
|
7bbcc44c5e | ||
|
|
25475a88a7 | ||
|
|
db49c29627 | ||
|
|
c237553508 | ||
|
|
0c96d32754 | ||
|
|
3f83f279d7 | ||
|
|
82fe9fa6df | ||
|
|
983d9a428d | ||
|
|
2fa77d8295 | ||
|
|
f53afc1d2d |
No files matched your search
@@ -1 +1,8 @@
|
||||
* text=auto eol=lf
|
||||
lvglh/** linguist-vendored
|
||||
lvgl/** linguist-vendored
|
||||
.vscode/* linguist-vendored
|
||||
lib/* linguist-generated
|
||||
release/* linguist-generated
|
||||
iso/* linguist-generated
|
||||
*.asm linguist-detectable
|
||||
@@ -15,3 +15,4 @@ localenv.json
|
||||
dockerout.txt
|
||||
AGENTS.md
|
||||
*.log
|
||||
/doc/*.md
|
||||
+1
-1
@@ -4,4 +4,4 @@ echo "======================="
|
||||
echo " "
|
||||
echo "Compiling FPC Sources..."
|
||||
echo " "
|
||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/include/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
|
||||
Whitespace-only changes.
@@ -18,7 +18,7 @@
|
||||
@author(Aaron Hance <[email protected]>)
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit PCI;
|
||||
unit pci;
|
||||
|
||||
interface
|
||||
|
||||
|
||||
+1768
-39
File diff suppressed because it is too large.
Load diff
@@ -7,7 +7,7 @@
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit OHCI;
|
||||
unit ohci;
|
||||
|
||||
interface
|
||||
|
||||
@@ -23,6 +23,7 @@ uses
|
||||
drivermanagement,
|
||||
usbtypes,
|
||||
usbcore,
|
||||
isrmanager,
|
||||
lists,
|
||||
strings;
|
||||
|
||||
@@ -234,6 +235,7 @@ type
|
||||
EDBulk : POHCI_ED; { Head of bulk ED list }
|
||||
EDInterrupt : POHCI_ED; { Dummy head for interrupt ED list }
|
||||
NumPorts : uint8; { Number of downstream ports }
|
||||
PollBusy : boolean; { Re-entrancy guard for poll }
|
||||
PCIBus : uint8; { PCI address }
|
||||
PCISlot : uint8;
|
||||
PCIFunc : uint8;
|
||||
@@ -1022,6 +1024,60 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ ========================= Interrupt-Driven Completion ========================= }
|
||||
|
||||
const
|
||||
OHCI_MAX_INSTANCES = 4;
|
||||
|
||||
var
|
||||
OHCIInstances : array[0..OHCI_MAX_INSTANCES-1] of PUSBHCDriver;
|
||||
OHCIInstanceCount : uint32;
|
||||
|
||||
{ ISR handler — registered on the PCI interrupt line. }
|
||||
procedure ohci_isr;
|
||||
var
|
||||
i : uint32;
|
||||
hc : PUSBHCDriver;
|
||||
priv : POHCI_PrivData;
|
||||
intSts : uint32;
|
||||
begin
|
||||
for i := 0 to OHCIInstanceCount - 1 do begin
|
||||
hc := OHCIInstances[i];
|
||||
if hc = nil then continue;
|
||||
priv := POHCI_PrivData(hc^.PrivData);
|
||||
if priv = nil then continue;
|
||||
|
||||
{ Check if this controller has pending interrupt status }
|
||||
intSts := ohci_read(priv^.MMIOBase, OHCI_REG_INTSTATUS);
|
||||
if intSts = 0 then continue;
|
||||
|
||||
{ Acknowledge interrupt status NOW to de-assert level-triggered PCI line.
|
||||
Must happen before ohci_poll, because PollBusy guard may skip the
|
||||
acknowledge inside poll — leaving the line asserted = interrupt storm. }
|
||||
ohci_write(priv^.MMIOBase, OHCI_REG_INTSTATUS, intSts);
|
||||
|
||||
{ Process completions (walks ED lists) }
|
||||
ohci_poll(hc);
|
||||
|
||||
{ Hotplug: if RootHubStatusChange, flag for deferred processing }
|
||||
if ((intSts AND OHCI_INT_RHSC) <> 0) and hc^.HotplugArmed then
|
||||
hc^.PortChangePending := true;
|
||||
end;
|
||||
usbcore.fire_completion_hooks;
|
||||
end;
|
||||
|
||||
{ Enable hardware interrupts: WritebackDoneHead, RootHubStatusChange, UnrecoverableError + MIE. }
|
||||
procedure ohci_enable_interrupts(hc : PUSBHCDriver);
|
||||
var
|
||||
priv : POHCI_PrivData;
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := POHCI_PrivData(hc^.PrivData);
|
||||
ohci_write(priv^.MMIOBase, OHCI_REG_INTENABLE,
|
||||
OHCI_INT_WDH OR OHCI_INT_RHSC OR OHCI_INT_UE OR OHCI_INT_MIE);
|
||||
syslog.logln('OHCI', 'Hardware interrupts enabled.');
|
||||
end;
|
||||
|
||||
procedure ohci_poll(hc : PUSBHCDriver);
|
||||
var
|
||||
priv : POHCI_PrivData;
|
||||
@@ -1038,6 +1094,11 @@ var
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := POHCI_PrivData(hc^.PrivData);
|
||||
|
||||
{ Re-entrancy guard }
|
||||
if priv^.PollBusy then exit;
|
||||
priv^.PollBusy := true;
|
||||
|
||||
base := priv^.MMIOBase;
|
||||
|
||||
{ Read and acknowledge interrupt status }
|
||||
@@ -1107,6 +1168,7 @@ begin
|
||||
ed := nextED;
|
||||
end;
|
||||
end;
|
||||
priv^.PollBusy := false;
|
||||
end;
|
||||
|
||||
{ ========================= Load / Init ========================= }
|
||||
@@ -1124,6 +1186,7 @@ var
|
||||
begin
|
||||
push_trace('OHCI.load');
|
||||
load := false;
|
||||
OHCIInstanceCount := 0;
|
||||
|
||||
devices := PCI.getDeviceInfo($0C, $03, $10, count);
|
||||
syslog.log('OHCI', 'Found ');
|
||||
@@ -1220,9 +1283,24 @@ begin
|
||||
hcEntry := usbcore.register_hc(@hc);
|
||||
|
||||
{ Scan ports for connected devices (use the stable pointer, not stack-local @hc) }
|
||||
if hcEntry <> nil then
|
||||
usbcore.scan_ports(hcEntry)
|
||||
else
|
||||
if hcEntry <> nil then begin
|
||||
{ Track instance for ISR dispatch }
|
||||
if OHCIInstanceCount < OHCI_MAX_INSTANCES then begin
|
||||
OHCIInstances[OHCIInstanceCount] := hcEntry;
|
||||
inc(OHCIInstanceCount);
|
||||
end;
|
||||
|
||||
{ Register ISR on PCI interrupt line }
|
||||
syslog.log('OHCI', 'Registering ISR on IRQ ');
|
||||
syslog.writeintln(devices[i].interrupt_line);
|
||||
isrmanager.registerISR(32 + devices[i].interrupt_line, @ohci_isr);
|
||||
|
||||
{ Enable hardware interrupts }
|
||||
ohci_enable_interrupts(hcEntry);
|
||||
|
||||
{ Scan for connected devices }
|
||||
usbcore.scan_ports(hcEntry);
|
||||
end else
|
||||
syslog.logln('OHCI', 'Failed to register HC with USB core.');
|
||||
|
||||
syslog.logln('OHCI', 'Controller initialized and registered.');
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit UHCI;
|
||||
unit uhci;
|
||||
|
||||
interface
|
||||
|
||||
@@ -22,6 +22,7 @@ uses
|
||||
drivermanagement,
|
||||
usbtypes,
|
||||
usbcore,
|
||||
isrmanager,
|
||||
lists,
|
||||
strings;
|
||||
|
||||
@@ -154,6 +155,7 @@ type
|
||||
QHControl : PUHCI_QH; { Queue Head for control transfers }
|
||||
QHBulk : PUHCI_QH; { Queue Head for bulk transfers }
|
||||
QHInterrupt : PUHCI_QH; { Queue Head for interrupt transfers }
|
||||
PollBusy : boolean; { Re-entrancy guard for poll }
|
||||
PCIBus : uint8; { PCI bus/slot/func for bus mastering }
|
||||
PCISlot : uint8;
|
||||
PCIFunc : uint8;
|
||||
@@ -750,6 +752,56 @@ begin
|
||||
pop_trace;
|
||||
end;
|
||||
|
||||
{ ========================= Interrupt-Driven Completion ========================= }
|
||||
|
||||
const
|
||||
UHCI_MAX_INSTANCES = 4;
|
||||
|
||||
var
|
||||
UHCIInstances : array[0..UHCI_MAX_INSTANCES-1] of PUSBHCDriver;
|
||||
UHCIInstanceCount : uint32;
|
||||
|
||||
{ ISR handler — registered on the PCI interrupt line. }
|
||||
procedure uhci_isr;
|
||||
var
|
||||
i : uint32;
|
||||
hc : PUSBHCDriver;
|
||||
priv : PUHCI_PrivData;
|
||||
status : uint16;
|
||||
begin
|
||||
for i := 0 to UHCIInstanceCount - 1 do begin
|
||||
hc := UHCIInstances[i];
|
||||
if hc = nil then continue;
|
||||
priv := PUHCI_PrivData(hc^.PrivData);
|
||||
if priv = nil then continue;
|
||||
|
||||
{ Check if this controller has pending interrupt status }
|
||||
status := uhci_read16(priv^.IOBase, UHCI_REG_USBSTS);
|
||||
if (status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR)) = 0 then continue;
|
||||
|
||||
{ Acknowledge interrupt status NOW to de-assert level-triggered PCI line.
|
||||
Must happen before uhci_poll, because PollBusy guard may skip the
|
||||
acknowledge inside poll — leaving the line asserted = interrupt storm. }
|
||||
uhci_write16(priv^.IOBase, UHCI_REG_USBSTS, status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR));
|
||||
|
||||
{ Process completions (walks QH/TD chains) }
|
||||
uhci_poll(hc);
|
||||
end;
|
||||
usbcore.fire_completion_hooks;
|
||||
end;
|
||||
|
||||
{ Enable hardware interrupts: Interrupt-on-Complete, Short Packet, Timeout/CRC. }
|
||||
procedure uhci_enable_interrupts(hc : PUSBHCDriver);
|
||||
var
|
||||
priv : PUHCI_PrivData;
|
||||
begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := PUHCI_PrivData(hc^.PrivData);
|
||||
uhci_write16(priv^.IOBase, UHCI_REG_USBINTR,
|
||||
UHCI_INTR_IOC OR UHCI_INTR_SP OR UHCI_INTR_TIMEOUT);
|
||||
syslog.logln('UHCI', 'Hardware interrupts enabled.');
|
||||
end;
|
||||
|
||||
{ ========================= Poll / Completion ========================= }
|
||||
|
||||
procedure uhci_poll(hc : PUSBHCDriver);
|
||||
@@ -768,6 +820,10 @@ begin
|
||||
if (hc = nil) or (hc^.PrivData = nil) then exit;
|
||||
priv := PUHCI_PrivData(hc^.PrivData);
|
||||
|
||||
{ Re-entrancy guard }
|
||||
if priv^.PollBusy then exit;
|
||||
priv^.PollBusy := true;
|
||||
|
||||
{ Read and clear status register }
|
||||
status := uhci_read16(priv^.IOBase, UHCI_REG_USBSTS);
|
||||
if (status AND (UHCI_STS_USBINT OR UHCI_STS_ERROR)) <> 0 then
|
||||
@@ -841,6 +897,7 @@ begin
|
||||
end;
|
||||
qh := qh^.SWNext;
|
||||
end;
|
||||
priv^.PollBusy := false;
|
||||
end;
|
||||
|
||||
{ ========================= Load / Init ========================= }
|
||||
@@ -857,6 +914,7 @@ var
|
||||
begin
|
||||
push_trace('UHCI.load');
|
||||
load := false;
|
||||
UHCIInstanceCount := 0;
|
||||
|
||||
devices := PCI.getDeviceInfo($0C, $03, $00, count);
|
||||
syslog.log('UHCI', 'Found ');
|
||||
@@ -945,9 +1003,24 @@ begin
|
||||
hcEntry := usbcore.register_hc(@hc);
|
||||
|
||||
{ Scan ports for connected devices (use the stable pointer, not stack-local @hc) }
|
||||
if hcEntry <> nil then
|
||||
usbcore.scan_ports(hcEntry)
|
||||
else
|
||||
if hcEntry <> nil then begin
|
||||
{ Track instance for ISR dispatch }
|
||||
if UHCIInstanceCount < UHCI_MAX_INSTANCES then begin
|
||||
UHCIInstances[UHCIInstanceCount] := hcEntry;
|
||||
inc(UHCIInstanceCount);
|
||||
end;
|
||||
|
||||
{ Register ISR on PCI interrupt line }
|
||||
syslog.log('UHCI', 'Registering ISR on IRQ ');
|
||||
syslog.writeintln(devices[i].interrupt_line);
|
||||
isrmanager.registerISR(32 + devices[i].interrupt_line, @uhci_isr);
|
||||
|
||||
{ Enable hardware interrupts }
|
||||
uhci_enable_interrupts(hcEntry);
|
||||
|
||||
{ Scan for connected devices }
|
||||
usbcore.scan_ports(hcEntry);
|
||||
end else
|
||||
syslog.logln('UHCI', 'Failed to register HC with USB core.');
|
||||
|
||||
syslog.logln('UHCI', 'Controller initialized and registered.');
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit USB;
|
||||
unit usb;
|
||||
|
||||
interface
|
||||
|
||||
@@ -35,6 +35,7 @@ uses
|
||||
usbhub,
|
||||
usb_keyboard,
|
||||
usb_mouse,
|
||||
usb_storage,
|
||||
OHCI, UHCI, EHCI, XHCI;
|
||||
|
||||
procedure init;
|
||||
@@ -90,6 +91,9 @@ begin
|
||||
usb_keyboard.init;
|
||||
usb_mouse.init;
|
||||
|
||||
{ Initialize storage class driver }
|
||||
usb_storage.init;
|
||||
|
||||
UHCI_ID.Bus:= biPCI;
|
||||
UHCI_ID.id0:= idANY;
|
||||
UHCI_ID.id1:= $0000000C;
|
||||
|
||||
+2361
-39
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -217,6 +217,9 @@ type
|
||||
PUSBHCDriver = ^TUSBHCDriver;
|
||||
PUSBTransfer = ^TUSBTransfer;
|
||||
|
||||
{ ---- Disconnect Callback ---- }
|
||||
TUSBDisconnectCallback = procedure(dev : PUSBDevice);
|
||||
|
||||
{ ---- Transfer Request ---- }
|
||||
|
||||
TUSBTransfer = record
|
||||
@@ -246,6 +249,7 @@ type
|
||||
Endpoints : array[0..USB_MAX_ENDPOINTS-1] of TUSBEndpoint;
|
||||
NumEndpoints : uint8;
|
||||
Configured : boolean;
|
||||
fnDisconnect : TUSBDisconnectCallback; { Called before device is freed on unplug }
|
||||
end;
|
||||
|
||||
{ ---- HC Driver Abstraction (Function Pointer Types) ---- }
|
||||
@@ -269,6 +273,8 @@ type
|
||||
PrivData : Pointer; { HC-specific state }
|
||||
Devices : PLinkedListBase; { List of PUSBDevice attached }
|
||||
NextAddress : uint8; { Next available USB address (1-127) }
|
||||
PortChangePending : boolean; { Set by ISR when port status changes; processed in deferred context }
|
||||
HotplugArmed : boolean; { False during boot; set true after initial scan_ports to ignore spurious RHSC }
|
||||
{ Operations }
|
||||
fnReset : TUSBHCReset;
|
||||
fnStart : TUSBHCStart;
|
||||
|
||||
@@ -32,32 +32,41 @@ uses
|
||||
|
||||
procedure callback(scan_code : void);
|
||||
var
|
||||
info : TKeyInfo;
|
||||
info : TKeyInfo;
|
||||
raw : uint8;
|
||||
baseCode : uint8;
|
||||
isBreak : boolean;
|
||||
begin
|
||||
info.SHIFT_DOWN := keyboard.is_shift;
|
||||
info.CTRL_DOWN := keyboard.is_ctrl;
|
||||
info.ALT_DOWN := keyboard.is_alt;
|
||||
info.is_down_code := true;
|
||||
raw := uint8(scan_code);
|
||||
|
||||
{ In PS/2 scancode set 1, bit 7 set = key release (break code) }
|
||||
isBreak := (raw AND $80) <> 0;
|
||||
baseCode := raw AND $7F;
|
||||
|
||||
{ Update modifier state (use raw codes so both make/break are handled) }
|
||||
if raw = 42 then keyboard.is_shift := true;
|
||||
if raw = 170 then keyboard.is_shift := false;
|
||||
if raw = 29 then keyboard.is_ctrl := true;
|
||||
if raw = 157 then keyboard.is_ctrl := false;
|
||||
if raw = 56 then keyboard.is_alt := true;
|
||||
if raw = 184 then keyboard.is_alt := false;
|
||||
|
||||
info.SHIFT_DOWN := keyboard.is_shift;
|
||||
info.CTRL_DOWN := keyboard.is_ctrl;
|
||||
info.ALT_DOWN := keyboard.is_alt;
|
||||
info.is_down_code := not isBreak;
|
||||
|
||||
if keyboard.is_shift then begin
|
||||
if key_matrix_shift[uint8(scan_code)].key_code <> 0 then begin
|
||||
info.key_code := key_matrix_shift[uint8(scan_code)].key_code;
|
||||
if key_matrix_shift[baseCode].key_code <> 0 then begin
|
||||
info.key_code := key_matrix_shift[baseCode].key_code;
|
||||
keyboard.reportKeyEvent(info);
|
||||
end;
|
||||
end else begin
|
||||
if key_matrix[uint8(scan_code)].key_code <> 0 then begin
|
||||
info.key_code := key_matrix[uint8(scan_code)].key_code;
|
||||
if key_matrix[baseCode].key_code <> 0 then begin
|
||||
info.key_code := key_matrix[baseCode].key_code;
|
||||
keyboard.reportKeyEvent(info);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Update modifier state }
|
||||
if uint8(scan_code) = 42 then keyboard.is_shift := true;
|
||||
if uint8(scan_code) = 170 then keyboard.is_shift := false;
|
||||
if uint8(scan_code) = 29 then keyboard.is_ctrl := true;
|
||||
if uint8(scan_code) = 157 then keyboard.is_ctrl := false;
|
||||
if uint8(scan_code) = 56 then keyboard.is_alt := true;
|
||||
if uint8(scan_code) = 184 then keyboard.is_alt := false;
|
||||
end;
|
||||
|
||||
function load(ptr : void) : boolean;
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,52 @@
|
||||
{
|
||||
Driver->Timer->GraphicsRefresh - Timer-driven graphics refresh at ~120FPS.
|
||||
|
||||
Hooks into the 1024Hz timer (TMR_0_ISR) and calls the desktop, uidebug,
|
||||
LVGL and video flush routines every ~9 ticks (1024/9 ≈ 113.8 FPS).
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit graphicsrefresh;
|
||||
|
||||
interface
|
||||
|
||||
procedure init;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
util,
|
||||
TMR_0_ISR,
|
||||
desktop,
|
||||
uidebug,
|
||||
lvgl,
|
||||
video,
|
||||
syslog;
|
||||
|
||||
const
|
||||
{ 1024 / 4 ≈ 256 FPS }
|
||||
TICKS_PER_FRAME = 4;
|
||||
|
||||
var
|
||||
TickCounter : uint32;
|
||||
|
||||
procedure on_tick(data : void);
|
||||
begin
|
||||
TickCounter := TickCounter + 1;
|
||||
if TickCounter >= TICKS_PER_FRAME then begin
|
||||
TickCounter := 0;
|
||||
desktop.update;
|
||||
uidebug.update;
|
||||
lvgl_handler;
|
||||
video.Flush;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
TickCounter := 0;
|
||||
TMR_0_ISR.hook(uint32(@on_tick));
|
||||
syslog.logln('GFXREFRESH', 'Hooked into 1024Hz timer (~120 FPS).');
|
||||
end;
|
||||
|
||||
end.
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
Driver->Timer->USBHotplug - Timer-driven USB hotplug polling at ~1Hz.
|
||||
|
||||
Hooks into the 1024Hz timer (TMR_0_ISR) and calls
|
||||
usbcore.usb_check_hotplug every 1024 ticks (approximately once per second).
|
||||
|
||||
@author(Kieron Morris <[email protected]>)
|
||||
}
|
||||
unit usbhotplug;
|
||||
|
||||
interface
|
||||
|
||||
procedure init;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
util,
|
||||
TMR_0_ISR,
|
||||
usbcore,
|
||||
syslog;
|
||||
|
||||
const
|
||||
{ 1024 ticks at 1024Hz ≈ 1 second }
|
||||
TICKS_PER_POLL = 1024;
|
||||
|
||||
var
|
||||
TickCounter : uint32;
|
||||
|
||||
procedure on_tick(data : void);
|
||||
begin
|
||||
TickCounter := TickCounter + 1;
|
||||
if TickCounter >= TICKS_PER_POLL then begin
|
||||
TickCounter := 0;
|
||||
usbcore.usb_check_hotplug;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure init;
|
||||
begin
|
||||
TickCounter := 0;
|
||||
TMR_0_ISR.hook(uint32(@on_tick));
|
||||
syslog.logln('USBHOTPLUG', 'Hooked into 1024Hz timer (~1Hz polling).');
|
||||
end;
|
||||
|
||||
end.
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Loaded 20 of 32 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user