From a79371f418d4f47a084fff93807e2e4f1149581b Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Tue, 31 Dec 2024 01:15:26 +0100 Subject: [PATCH] Separate PLL config for RP2040 and RP2350 --- src/machine/machine_rp2_2040.go | 15 ++++++++++++++- src/machine/machine_rp2_2350.go | 14 ++++++++++++++ src/machine/machine_rp2_clocks.go | 30 +++++++++++++++--------------- src/machine/machine_rp2_i2c.go | 2 +- src/machine/machine_rp2_spi.go | 4 ++-- src/machine/machine_rp2_uart.go | 2 +- 6 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/machine/machine_rp2_2040.go b/src/machine/machine_rp2_2040.go index 484d8e923a..bcb24bd87c 100644 --- a/src/machine/machine_rp2_2040.go +++ b/src/machine/machine_rp2_2040.go @@ -113,6 +113,19 @@ const ( fnXIP pinFunc = 0 ) +// System clock configuration +const ( + pllSysFreq uint32 = 125*MHz + pllSysVcoFreq = 1500*MHz + pllSysPostDiv1 = 6 + pllSysPostDiv2 = 2 + + pllUSBFreq uint32 = 48*MHz + pllUSBVcoFreq = 480*MHz + pllUSBPostDiv1 = 5 + pllUSBPostDiv2 = 2 +) + // Configure configures the gpio pin as per mode. func (p Pin) Configure(config PinConfig) { if p == NoPin { @@ -184,7 +197,7 @@ func (clks *clocksType) initRTC() { crtc := clks.clock(clkRTC) crtc.configure(0, // No GLMUX rp.CLOCKS_CLK_RTC_CTRL_AUXSRC_CLKSRC_PLL_USB, - 48*MHz, + pllUSBFreq, 46875) } diff --git a/src/machine/machine_rp2_2350.go b/src/machine/machine_rp2_2350.go index 4e12bebe35..329e301fee 100644 --- a/src/machine/machine_rp2_2350.go +++ b/src/machine/machine_rp2_2350.go @@ -120,6 +120,20 @@ const ( fnNULL pinFunc = 0x1f ) +// System clock configuration +// Note that VcoFreq, PostDiv1, and PostDiv2 must be manually calculated to achive desired output frequency. +const ( + pllSysFreq uint32 = 150*MHz + pllSysVcoFreq = 1500*MHz + pllSysPostDiv1 = 5 + pllSysPostDiv2 = 2 + + pllUSBFreq uint32 = 48*MHz + pllUSBVcoFreq = 480*MHz + pllUSBPostDiv1 = 5 + pllUSBPostDiv2 = 2 +) + // Configure configures the gpio pin as per mode. func (p Pin) Configure(config PinConfig) { if p == NoPin { diff --git a/src/machine/machine_rp2_clocks.go b/src/machine/machine_rp2_clocks.go index cc152a7f82..b4ef0dcee8 100644 --- a/src/machine/machine_rp2_clocks.go +++ b/src/machine/machine_rp2_clocks.go @@ -10,13 +10,13 @@ import ( ) func CPUFrequency() uint32 { - return 125 * MHz + return pllSysFreq } // Returns the period of a clock cycle for the raspberry pi pico in nanoseconds. // Used in PWM API. func cpuPeriod() uint32 { - return 1e9 / CPUFrequency() + return uint32(1e9) / pllSysFreq // TODO: Discards remainder } // clockIndex identifies a hardware clock @@ -168,9 +168,9 @@ func (clks *clocksType) init() { // Configure PLLs // REF FBDIV VCO POSTDIV // pllSys: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz + pllSys.init(1, pllSysVcoFreq, pllSysPostDiv1, pllSysPostDiv2) // pllUSB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz - pllSys.init(1, 1500*MHz, 6, 2) - pllUSB.init(1, 480*MHz, 5, 2) + pllUSB.init(1, pllUSBVcoFreq, pllUSBPostDiv1, pllUSBPostDiv2) // Configure clocks // clkRef = xosc (12MHz) / 1 = 12MHz @@ -180,26 +180,26 @@ func (clks *clocksType) init() { 12*MHz, 12*MHz) - // clkSys = pllSys (125MHz) / 1 = 125MHz + // clkSys = pllSys (pllSysFreq) / 1 = pllSysFreq csys := clks.clock(clkSys) csys.configure(rp.CLOCKS_CLK_SYS_CTRL_SRC_CLKSRC_CLK_SYS_AUX, rp.CLOCKS_CLK_SYS_CTRL_AUXSRC_CLKSRC_PLL_SYS, - 125*MHz, - 125*MHz) + pllSysFreq, + pllSysFreq) - // clkUSB = pllUSB (48MHz) / 1 = 48MHz + // clkUSB = pllUSB (pllUSBFreq) / 1 = 48MHz cusb := clks.clock(clkUSB) cusb.configure(0, // No GLMUX rp.CLOCKS_CLK_USB_CTRL_AUXSRC_CLKSRC_PLL_USB, - 48*MHz, - 48*MHz) + pllUSBFreq, + pllUSBFreq) - // clkADC = pllUSB (48MHZ) / 1 = 48MHz + // clkADC = pllUSB (pllUSBFreq) / 1 = 48MHz cadc := clks.clock(clkADC) cadc.configure(0, // No GLMUX rp.CLOCKS_CLK_ADC_CTRL_AUXSRC_CLKSRC_PLL_USB, - 48*MHz, - 48*MHz) + pllUSBFreq, + pllUSBFreq) clks.initRTC() @@ -209,8 +209,8 @@ func (clks *clocksType) init() { cperi := clks.clock(clkPeri) cperi.configure(0, rp.CLOCKS_CLK_PERI_CTRL_AUXSRC_CLK_SYS, - 125*MHz, - 125*MHz) + pllSysFreq, + pllSysFreq) clks.initTicks() } diff --git a/src/machine/machine_rp2_i2c.go b/src/machine/machine_rp2_i2c.go index 2552eb94e6..cf267eac67 100644 --- a/src/machine/machine_rp2_i2c.go +++ b/src/machine/machine_rp2_i2c.go @@ -162,7 +162,7 @@ func (i2c *I2C) SetBaudRate(br uint32) error { } // I2C is synchronous design that runs from clk_sys - freqin := CPUFrequency() + freqin := pllSysFreq // TODO there are some subtleties to I2C timing which we are completely ignoring here period := (freqin + br/2) / br diff --git a/src/machine/machine_rp2_spi.go b/src/machine/machine_rp2_spi.go index faab9839af..2bacb6e9e0 100644 --- a/src/machine/machine_rp2_spi.go +++ b/src/machine/machine_rp2_spi.go @@ -104,7 +104,7 @@ func (spi SPI) Transfer(w byte) (byte, error) { } func (spi SPI) SetBaudRate(br uint32) error { - const freqin uint32 = 125 * MHz + const freqin uint32 = pllSysFreq const maxBaud uint32 = 66.5 * MHz // max output frequency is 66.5MHz on rp2040. see Note page 527. // Find smallest prescale value which puts output frequency in range of // post-divide. Prescale is an even number from 2 to 254 inclusive. @@ -130,7 +130,7 @@ func (spi SPI) SetBaudRate(br uint32) error { } func (spi SPI) GetBaudRate() uint32 { - const freqin uint32 = 125 * MHz + const freqin uint32 = pllSysFreq prescale := spi.Bus.SSPCPSR.Get() postdiv := ((spi.Bus.SSPCR0.Get() & rp.SPI0_SSPCR0_SCR_Msk) >> rp.SPI0_SSPCR0_SCR_Pos) + 1 return freqin / (prescale * postdiv) diff --git a/src/machine/machine_rp2_uart.go b/src/machine/machine_rp2_uart.go index c984d41424..93d8d8924f 100644 --- a/src/machine/machine_rp2_uart.go +++ b/src/machine/machine_rp2_uart.go @@ -75,7 +75,7 @@ func (uart *UART) Configure(config UARTConfig) error { // SetBaudRate sets the baudrate to be used for the UART. func (uart *UART) SetBaudRate(br uint32) { - div := 8 * 125 * MHz / br + div := 8 * pllSysFreq / br ibrd := div >> 7 var fbrd uint32