Skip to content

Commit

Permalink
RP.Clock: allow custom settings for PLL_SYS
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabien-Chouteau authored and JeremyGrosser committed Dec 21, 2024
1 parent 57b8ab1 commit ef10b88
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 55 deletions.
10 changes: 6 additions & 4 deletions src/drivers/rp-clock.adb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ package body RP.Clock is
end Configure_PLL;

procedure Init_PLLs
(XOSC_Frequency : Hertz)
(XOSC_Frequency : Hertz;
SYS_PLL_Config : PLL_Config)
is
use RP.Reset;
begin
Expand All @@ -71,7 +72,7 @@ package body RP.Clock is
Reset_Peripheral (Reset_PLL_USB);

-- Assumes clk_ref = 12 MHz
Configure_PLL (PLL_SYS, PLL_125_MHz);
Configure_PLL (PLL_SYS, SYS_PLL_Config);
Configure_PLL (PLL_USB, PLL_48_MHz);

-- Switch clk_sys to pll_sys
Expand Down Expand Up @@ -108,7 +109,8 @@ package body RP.Clock is

procedure Initialize
(XOSC_Frequency : XOSC_Hertz := 0;
XOSC_Startup_Delay : XOSC_Cycles := 770_048)
XOSC_Startup_Delay : XOSC_Cycles := 770_048;
SYS_PLL_Config : PLL_Config := PLL_125_MHz)
is
use RP2040_SVD.WATCHDOG;
Reference : Hertz;
Expand All @@ -124,7 +126,7 @@ package body RP.Clock is
Reference := XOSC_Frequency;
RP2040_SVD.XOSC.XOSC_Periph.STARTUP.DELAY_k := RP2040_SVD.XOSC.STARTUP_DELAY_Field (XOSC_Startup_Delay / 256);
Set_SYS_Source (XOSC);
Init_PLLs (XOSC_Frequency);
Init_PLLs (XOSC_Frequency, SYS_PLL_Config);
else
Reference := ROSC_Frequency;
Set_SYS_Source (ROSC);
Expand Down
107 changes: 56 additions & 51 deletions src/drivers/rp-clock.ads
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,6 @@ is

subtype XOSC_Cycles is Natural;

procedure Initialize
(XOSC_Frequency : XOSC_Hertz := 0;
XOSC_Startup_Delay : XOSC_Cycles := 770_048) -- ~64ms with a 12 MHz crystal
with Pre => XOSC_Startup_Delay <= (Natural (UInt14'Last) * 256)
and XOSC_Startup_Delay mod 256 = 0;
-- See 2.16.3 Startup Delay for XOSC_Startup_Delay calculation. The default
-- value is approximately 1ms with a 12 MHz crystal.

-- Currently we have hardcoded PLL divider values for 12 MHz ROSC or XOSC
-- operation. This exception is thrown if any other reference frequency is
-- given or Enable_PLL is called with invalid arguments.
Invalid_PLL_Config : exception;

type Clock_Id is
(GPOUT0, GPOUT1, GPOUT2, GPOUT3, REF, SYS, PERI, USB, ADC, RTC,
PLL_SYS, GPIN0, GPIN1, PLL_USB, ROSC, XOSC);

procedure Enable
(CID : Clock_Id);

procedure Disable
(CID : Clock_Id);

subtype GP_Output is Clock_Id range GPOUT0 .. GPOUT3;
subtype GP_Source is Clock_Id range REF .. XOSC;

procedure Set_Source
(GP : GP_Output;
Source : GP_Source);
-- GP will glitch if enabled while changing sources

GP_Divider_Fraction : constant := 1.0 / (2 ** 8);
type GP_Divider is delta GP_Divider_Fraction range 0.0 .. (2.0 ** 24) - GP_Divider_Fraction
with Small => GP_Divider_Fraction,
Size => 32;
-- If GP_Divider is 0.0, then it represents (2.0 ** 16)

procedure Set_Divider
(GP : GP_Output;
Div : GP_Divider);

function Enabled
(CID : Clock_Id)
return Boolean;

subtype SYS_Clock_Id is Clock_Id range PLL_SYS .. XOSC;
procedure Set_SYS_Source
(Source : SYS_Clock_Id);

subtype PLL_Clock_Id is Clock_Id
with Static_Predicate => PLL_Clock_Id in PLL_SYS | PLL_USB;
subtype PLL_FREF_Field is Hertz range 5_000_000 .. 800_000_000;
subtype PLL_REFDIV_Field is UInt6 range 1 .. 63;
subtype PLL_FBDIV_Field is UInt12 range 16 .. 320;
Expand Down Expand Up @@ -113,6 +62,62 @@ is
POSTDIV1 => 6,
POSTDIV2 => 1);

procedure Initialize
(XOSC_Frequency : XOSC_Hertz := 0;
XOSC_Startup_Delay : XOSC_Cycles := 770_048; -- ~64ms with a 12 MHz crystal
SYS_PLL_Config : PLL_Config := PLL_125_MHz)
with Pre => XOSC_Startup_Delay <= (Natural (UInt14'Last) * 256)
and XOSC_Startup_Delay mod 256 = 0;
-- See 2.16.3 Startup Delay for XOSC_Startup_Delay calculation. The default
-- value is approximately 64ms with a 12 MHz crystal.
--
-- The SYS_PLL_Config parameter allows for a custom configuration of the
-- system PLL that drives the CPU cores and peripherals.

-- Currently we have hardcoded PLL divider values for 12 MHz ROSC or XOSC
-- operation. This exception is thrown if any other reference frequency is
-- given or Enable_PLL is called with invalid arguments.
Invalid_PLL_Config : exception;

type Clock_Id is
(GPOUT0, GPOUT1, GPOUT2, GPOUT3, REF, SYS, PERI, USB, ADC, RTC,
PLL_SYS, GPIN0, GPIN1, PLL_USB, ROSC, XOSC);

subtype SYS_Clock_Id is Clock_Id range PLL_SYS .. XOSC;
procedure Set_SYS_Source
(Source : SYS_Clock_Id);

subtype PLL_Clock_Id is Clock_Id
with Static_Predicate => PLL_Clock_Id in PLL_SYS | PLL_USB;

procedure Enable
(CID : Clock_Id);

procedure Disable
(CID : Clock_Id);

subtype GP_Output is Clock_Id range GPOUT0 .. GPOUT3;
subtype GP_Source is Clock_Id range REF .. XOSC;

procedure Set_Source
(GP : GP_Output;
Source : GP_Source);
-- GP will glitch if enabled while changing sources

GP_Divider_Fraction : constant := 1.0 / (2 ** 8);
type GP_Divider is delta GP_Divider_Fraction range 0.0 .. (2.0 ** 24) - GP_Divider_Fraction
with Small => GP_Divider_Fraction,
Size => 32;
-- If GP_Divider is 0.0, then it represents (2.0 ** 16)

procedure Set_Divider
(GP : GP_Output;
Div : GP_Divider);

function Enabled
(CID : Clock_Id)
return Boolean;

procedure Configure_PLL
(PLL : PLL_Clock_Id;
Config : PLL_Config)
Expand Down

0 comments on commit ef10b88

Please sign in to comment.