From a79371f418d4f47a084fff93807e2e4f1149581b Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Tue, 31 Dec 2024 01:15:26 +0100 Subject: [PATCH 1/4] 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 From d87b667ebcc23da402a09bb4674d4d6cbdfbb1e4 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Thu, 2 Jan 2025 18:31:35 +0100 Subject: [PATCH 2/4] Fix linting --- src/machine/machine_rp2_2040.go | 18 +++++++++--------- src/machine/machine_rp2_2350.go | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/machine/machine_rp2_2040.go b/src/machine/machine_rp2_2040.go index bcb24bd87c..158c77a61f 100644 --- a/src/machine/machine_rp2_2040.go +++ b/src/machine/machine_rp2_2040.go @@ -115,15 +115,15 @@ const ( // 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 + 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. diff --git a/src/machine/machine_rp2_2350.go b/src/machine/machine_rp2_2350.go index 329e301fee..190d1f3284 100644 --- a/src/machine/machine_rp2_2350.go +++ b/src/machine/machine_rp2_2350.go @@ -123,15 +123,15 @@ const ( // 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 + 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. From b700e4b0adb401ece7b21387db3a9172bef11ea7 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Mon, 6 Jan 2025 11:46:19 +0100 Subject: [PATCH 3/4] Remove redundant ticks initialization --- src/machine/machine_rp2_2040.go | 2 -- src/machine/machine_rp2_2350.go | 10 ++++------ src/machine/machine_rp2_clocks.go | 2 -- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/machine/machine_rp2_2040.go b/src/machine/machine_rp2_2040.go index 158c77a61f..82d508be28 100644 --- a/src/machine/machine_rp2_2040.go +++ b/src/machine/machine_rp2_2040.go @@ -201,8 +201,6 @@ func (clks *clocksType) initRTC() { 46875) } -func (clks *clocksType) initTicks() {} // No ticks on RP2040 - // startTick starts the watchdog tick. // cycles needs to be a divider that when applied to the xosc input, // produces a 1MHz clock. So if the xosc frequency is 12MHz, diff --git a/src/machine/machine_rp2_2350.go b/src/machine/machine_rp2_2350.go index 190d1f3284..802a502279 100644 --- a/src/machine/machine_rp2_2350.go +++ b/src/machine/machine_rp2_2350.go @@ -213,12 +213,6 @@ func irqSet(num uint32, enabled bool) { func (clks *clocksType) initRTC() {} // No RTC on RP2350. -func (clks *clocksType) initTicks() { - rp.TICKS.SetTIMER0_CTRL_ENABLE(0) - rp.TICKS.SetTIMER0_CYCLES(12) - rp.TICKS.SetTIMER0_CTRL_ENABLE(1) -} - func EnterBootloader() { enterBootloader() } @@ -227,5 +221,9 @@ func EnterBootloader() { // On RP2040, the watchdog contained a tick generator used to generate a 1μs tick for the watchdog. This was also // distributed to the system timer. On RP2350, the watchdog instead takes a tick input from the system-level ticks block. See Section 8.5. func (wd *watchdogImpl) startTick(cycles uint32) { + rp.TICKS.SetTIMER0_CTRL_ENABLE(0) + rp.TICKS.SetTIMER0_CYCLES(cycles) + rp.TICKS.SetTIMER0_CTRL_ENABLE(1) + rp.TICKS.WATCHDOG_CTRL.SetBits(1) } diff --git a/src/machine/machine_rp2_clocks.go b/src/machine/machine_rp2_clocks.go index b4ef0dcee8..9ae77d1be9 100644 --- a/src/machine/machine_rp2_clocks.go +++ b/src/machine/machine_rp2_clocks.go @@ -211,6 +211,4 @@ func (clks *clocksType) init() { rp.CLOCKS_CLK_PERI_CTRL_AUXSRC_CLK_SYS, pllSysFreq, pllSysFreq) - - clks.initTicks() } From 586c88e4cdbaf4fbad178f3ecca171b53ba98a6b Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Mon, 6 Jan 2025 15:27:47 +0100 Subject: [PATCH 4/4] Move RP2 clock settings into structure, with machine default * Addresses #4673: input oscillator frequency can be changed for an individual board by filling in a custom PLL configuration --- src/machine/board_ae_rp2040.go | 6 +-- src/machine/board_badger2040-w.go | 6 +-- src/machine/board_badger2040.go | 6 +-- src/machine/board_challenger_rp2040.go | 6 +-- src/machine/board_feather_rp2040.go | 4 +- src/machine/board_gopher-badge.go | 6 +-- src/machine/board_kb2040.go | 4 +- src/machine/board_macropad-rp2040.go | 6 +-- src/machine/board_nano-rp2040.go | 6 +-- src/machine/board_pico.go | 6 +-- src/machine/board_pico2.go | 6 +-- src/machine/board_qtpy_rp2040.go | 4 +- src/machine/board_thingplus_rp2040.go | 4 +- src/machine/board_thumby.go | 6 +-- src/machine/board_tiny2350.go | 6 +-- src/machine/board_trinkey_qt2040.go | 4 +- src/machine/board_tufty2040.go | 6 +-- src/machine/board_waveshare-rp2040-zero.go | 6 +-- src/machine/board_xiao-rp2040.go | 6 +-- src/machine/machine_rp2_2040.go | 28 +++++++------ src/machine/machine_rp2_2350.go | 27 +++++++------ src/machine/machine_rp2_clocks.go | 46 ++++++++++++++-------- src/machine/machine_rp2_i2c.go | 2 +- src/machine/machine_rp2_pll.go | 2 +- src/machine/machine_rp2_spi.go | 4 +- src/machine/machine_rp2_uart.go | 2 +- src/machine/machine_rp2_xosc.go | 4 +- 27 files changed, 110 insertions(+), 109 deletions(-) diff --git a/src/machine/board_ae_rp2040.go b/src/machine/board_ae_rp2040.go index 716cf72b31..dc8d622f6a 100644 --- a/src/machine/board_ae_rp2040.go +++ b/src/machine/board_ae_rp2040.go @@ -31,11 +31,11 @@ const ( GP27 Pin = GPIO27 GP28 Pin = GPIO28 GP29 Pin = GPIO29 - - // Onboard crystal oscillator frequency, in MHz. - xoscFreq = 12 // MHz ) +// System clock configuration +var clockCfg = defaultSystemClockCfg + // I2C Default pins on Raspberry Pico. const ( I2C0_SDA_PIN = GP4 diff --git a/src/machine/board_badger2040-w.go b/src/machine/board_badger2040-w.go index d0982653b3..705ed1c45a 100644 --- a/src/machine/board_badger2040-w.go +++ b/src/machine/board_badger2040-w.go @@ -68,10 +68,8 @@ SPI0_CS_PIN Pin = QSPI_CS */ ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // USB CDC identifiers const ( diff --git a/src/machine/board_badger2040.go b/src/machine/board_badger2040.go index 73f802a909..a60c6afc91 100644 --- a/src/machine/board_badger2040.go +++ b/src/machine/board_badger2040.go @@ -67,10 +67,8 @@ SPI0_CS_PIN Pin = QSPI_CS */ ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // USB CDC identifiers const ( diff --git a/src/machine/board_challenger_rp2040.go b/src/machine/board_challenger_rp2040.go index 9a85aa0aef..aaa226cc3b 100644 --- a/src/machine/board_challenger_rp2040.go +++ b/src/machine/board_challenger_rp2040.go @@ -4,11 +4,11 @@ package machine const ( LED = GPIO24 - - // Onboard crystal oscillator frequency, in MHz. - xoscFreq = 12 // MHz ) +// System clock configuration +var clockCfg = defaultSystemClockCfg + // GPIO Pins const ( D5 = GPIO2 diff --git a/src/machine/board_feather_rp2040.go b/src/machine/board_feather_rp2040.go index 44091e56e9..eb8262a26e 100644 --- a/src/machine/board_feather_rp2040.go +++ b/src/machine/board_feather_rp2040.go @@ -2,8 +2,8 @@ package machine -// Onboard crystal oscillator frequency, in MHz. -const xoscFreq = 12 // MHz +// System clock configuration +var clockCfg = defaultSystemClockCfg // GPIO Pins const ( diff --git a/src/machine/board_gopher-badge.go b/src/machine/board_gopher-badge.go index 7af27118b2..76066554a6 100644 --- a/src/machine/board_gopher-badge.go +++ b/src/machine/board_gopher-badge.go @@ -61,10 +61,8 @@ const ( SPI1_SDI_PIN Pin = NoPin ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // USB CDC identifiers const ( diff --git a/src/machine/board_kb2040.go b/src/machine/board_kb2040.go index 1a6f353623..ac72653048 100644 --- a/src/machine/board_kb2040.go +++ b/src/machine/board_kb2040.go @@ -2,8 +2,8 @@ package machine -// Onboard crystal oscillator frequency, in MHz. -const xoscFreq = 12 // MHz +// System clock configuration +var clockCfg = defaultSystemClockCfg // GPIO Pins const ( diff --git a/src/machine/board_macropad-rp2040.go b/src/machine/board_macropad-rp2040.go index 78bd2b749e..0e2bba8be2 100644 --- a/src/machine/board_macropad-rp2040.go +++ b/src/machine/board_macropad-rp2040.go @@ -4,11 +4,11 @@ package machine const ( NeopixelCount = 12 - - // Onboard crystal oscillator frequency, in MHz. - xoscFreq = 12 // MHz ) +// System clock configuration +var clockCfg = defaultSystemClockCfg + const ( SWITCH = GPIO0 BUTTON = GPIO0 diff --git a/src/machine/board_nano-rp2040.go b/src/machine/board_nano-rp2040.go index 8155523134..2a5998e597 100644 --- a/src/machine/board_nano-rp2040.go +++ b/src/machine/board_nano-rp2040.go @@ -95,10 +95,8 @@ const ( NINA_SOFT_FLOWCONTROL = false ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // USB CDC identifiers // https://github.com/arduino/ArduinoCore-mbed/blob/master/variants/NANO_RP2040_CONNECT/pins_arduino.h diff --git a/src/machine/board_pico.go b/src/machine/board_pico.go index efbd6ef7dc..1e677947bb 100644 --- a/src/machine/board_pico.go +++ b/src/machine/board_pico.go @@ -33,11 +33,11 @@ const ( // Onboard LED LED Pin = GPIO25 - - // Onboard crystal oscillator frequency, in MHz. - xoscFreq = 12 // MHz ) +// System clock configuration +var clockCfg = defaultSystemClockCfg + // I2C Default pins on Raspberry Pico. const ( I2C0_SDA_PIN = GP4 diff --git a/src/machine/board_pico2.go b/src/machine/board_pico2.go index 327c542fbc..8b3d180e11 100644 --- a/src/machine/board_pico2.go +++ b/src/machine/board_pico2.go @@ -33,11 +33,11 @@ const ( // Onboard LED LED Pin = GPIO25 - - // Onboard crystal oscillator frequency, in MHz. - xoscFreq = 12 // MHz ) +// System clock configuration +var clockCfg = defaultSystemClockCfg + // I2C Default pins on Raspberry Pico. const ( I2C0_SDA_PIN = GP4 diff --git a/src/machine/board_qtpy_rp2040.go b/src/machine/board_qtpy_rp2040.go index 3eabf0c9b6..5056161cc6 100644 --- a/src/machine/board_qtpy_rp2040.go +++ b/src/machine/board_qtpy_rp2040.go @@ -2,8 +2,8 @@ package machine -// Onboard crystal oscillator frequency, in MHz. -const xoscFreq = 12 // MHz +// System clock configuration +var clockCfg = defaultSystemClockCfg // GPIO Pins const ( diff --git a/src/machine/board_thingplus_rp2040.go b/src/machine/board_thingplus_rp2040.go index 48292d261e..52c9a917bc 100644 --- a/src/machine/board_thingplus_rp2040.go +++ b/src/machine/board_thingplus_rp2040.go @@ -2,8 +2,8 @@ package machine -// Onboard crystal oscillator frequency, in MHz. -const xoscFreq = 12 // MHz +// System clock configuration +var clockCfg = defaultSystemClockCfg // GPIO Pins const ( diff --git a/src/machine/board_thumby.go b/src/machine/board_thumby.go index f89a8b7059..8bb8c0d7e2 100644 --- a/src/machine/board_thumby.go +++ b/src/machine/board_thumby.go @@ -49,10 +49,8 @@ const ( SPI1_SDI_PIN = NoPin ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // USB CDC identifiers const ( diff --git a/src/machine/board_tiny2350.go b/src/machine/board_tiny2350.go index f04fa061b6..fc466b5fa4 100644 --- a/src/machine/board_tiny2350.go +++ b/src/machine/board_tiny2350.go @@ -27,11 +27,11 @@ const ( LED_GREEN Pin = GPIO19 LED_BLUE Pin = GPIO20 LED = LED_RED - - // Onboard crystal oscillator frequency, in MHz. - xoscFreq = 12 // MHz ) +// System clock configuration +var clockCfg = defaultSystemClockCfg + // I2C Default pins on Tiny2350. const ( I2C0_SDA_PIN = GP12 diff --git a/src/machine/board_trinkey_qt2040.go b/src/machine/board_trinkey_qt2040.go index 1a49c6d927..b38f076e2a 100644 --- a/src/machine/board_trinkey_qt2040.go +++ b/src/machine/board_trinkey_qt2040.go @@ -13,8 +13,8 @@ package machine -// Onboard crystal oscillator frequency, in MHz -const xoscFreq = 12 // MHz +// System clock configuration +var clockCfg = defaultSystemClockCfg // Onboard LEDs const ( diff --git a/src/machine/board_tufty2040.go b/src/machine/board_tufty2040.go index 57d244f28b..0585f8283e 100644 --- a/src/machine/board_tufty2040.go +++ b/src/machine/board_tufty2040.go @@ -58,10 +58,8 @@ const ( SPI1_SDI_PIN Pin = NoPin ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // USB CDC identifiers const ( diff --git a/src/machine/board_waveshare-rp2040-zero.go b/src/machine/board_waveshare-rp2040-zero.go index 00ddc53a51..ce649211de 100644 --- a/src/machine/board_waveshare-rp2040-zero.go +++ b/src/machine/board_waveshare-rp2040-zero.go @@ -75,10 +75,8 @@ const ( SPI1_SDI_PIN Pin = D12 ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // UART pins const ( diff --git a/src/machine/board_xiao-rp2040.go b/src/machine/board_xiao-rp2040.go index b010314557..11474e00ab 100644 --- a/src/machine/board_xiao-rp2040.go +++ b/src/machine/board_xiao-rp2040.go @@ -63,10 +63,8 @@ const ( SPI1_SDI_PIN Pin = NoPin ) -// Onboard crystal oscillator frequency, in MHz. -const ( - xoscFreq = 12 // MHz -) +// System clock configuration +var clockCfg = defaultSystemClockCfg // UART pins const ( diff --git a/src/machine/machine_rp2_2040.go b/src/machine/machine_rp2_2040.go index 82d508be28..fe3c102f99 100644 --- a/src/machine/machine_rp2_2040.go +++ b/src/machine/machine_rp2_2040.go @@ -113,18 +113,20 @@ 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 -) +// Clock frequency and PLL configuration +var defaultSystemClockCfg = systemClockCfg{ + xoscFreq: 12, + + pllSysFreq: 125 * MHz, + pllSysVcoFreq: 1500 * MHz, + pllSysPostDiv1: 6, + pllSysPostDiv2: 2, + + pllUSBFreq: 48 * MHz, + pllUSBVcoFreq: 480 * MHz, + pllUSBPostDiv1: 5, + pllUSBPostDiv2: 2, +} // Configure configures the gpio pin as per mode. func (p Pin) Configure(config PinConfig) { @@ -197,7 +199,7 @@ func (clks *clocksType) initRTC() { crtc := clks.clock(clkRTC) crtc.configure(0, // No GLMUX rp.CLOCKS_CLK_RTC_CTRL_AUXSRC_CLKSRC_PLL_USB, - pllUSBFreq, + clockCfg.pllUSBFreq, 46875) } diff --git a/src/machine/machine_rp2_2350.go b/src/machine/machine_rp2_2350.go index 802a502279..94e837afad 100644 --- a/src/machine/machine_rp2_2350.go +++ b/src/machine/machine_rp2_2350.go @@ -120,19 +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 -) +// Clock frequency and PLL configuration +var defaultSystemClockCfg = systemClockCfg{ + xoscFreq: 12, + + pllSysFreq: 150 * MHz, + pllSysVcoFreq: 1500 * MHz, + pllSysPostDiv1: 5, + pllSysPostDiv2: 2, + + pllUSBFreq: 48 * MHz, + pllUSBVcoFreq: 480 * MHz, + pllUSBPostDiv1: 5, + pllUSBPostDiv2: 2, +} // Configure configures the gpio pin as per mode. func (p Pin) Configure(config PinConfig) { diff --git a/src/machine/machine_rp2_clocks.go b/src/machine/machine_rp2_clocks.go index 9ae77d1be9..83fea50aaa 100644 --- a/src/machine/machine_rp2_clocks.go +++ b/src/machine/machine_rp2_clocks.go @@ -10,13 +10,13 @@ import ( ) func CPUFrequency() uint32 { - return pllSysFreq + return clockCfg.pllSysFreq } // Returns the period of a clock cycle for the raspberry pi pico in nanoseconds. // Used in PWM API. func cpuPeriod() uint32 { - return uint32(1e9) / pllSysFreq // TODO: Discards remainder + return uint32(1e9) / clockCfg.pllSysFreq // TODO: Discards remainder } // clockIndex identifies a hardware clock @@ -143,12 +143,26 @@ func (clk *clock) configure(src, auxsrc, srcFreq, freq uint32) { } +type systemClockCfg struct { + xoscFreq uint32 + + pllSysFreq uint32 + pllSysVcoFreq uint32 + pllSysPostDiv1 uint32 + pllSysPostDiv2 uint32 + + pllUSBFreq uint32 + pllUSBVcoFreq uint32 + pllUSBPostDiv1 uint32 + pllUSBPostDiv2 uint32 +} + // init initializes the clock hardware. // // Must be called before any other clock function. func (clks *clocksType) init() { // Start the watchdog tick - Watchdog.startTick(xoscFreq) + Watchdog.startTick(clockCfg.xoscFreq) // Disable resus that may be enabled from previous software rp.CLOCKS.SetCLK_SYS_RESUS_CTRL_CLEAR(0) @@ -168,38 +182,38 @@ 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) + pllSys.init(1, clockCfg.pllSysVcoFreq, clockCfg.pllSysPostDiv1, clockCfg.pllSysPostDiv2) // pllUSB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz - pllUSB.init(1, pllUSBVcoFreq, pllUSBPostDiv1, pllUSBPostDiv2) + pllUSB.init(1, clockCfg.pllUSBVcoFreq, clockCfg.pllUSBPostDiv1, clockCfg.pllUSBPostDiv2) // Configure clocks - // clkRef = xosc (12MHz) / 1 = 12MHz + // clkRef = xosc (xoscFreq) / 1 = xoscFreq cref := clks.clock(clkRef) cref.configure(rp.CLOCKS_CLK_REF_CTRL_SRC_XOSC_CLKSRC, 0, // No aux mux - 12*MHz, - 12*MHz) + clockCfg.xoscFreq, + clockCfg.xoscFreq) // 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, - pllSysFreq, - pllSysFreq) + clockCfg.pllSysFreq, + clockCfg.pllSysFreq) // clkUSB = pllUSB (pllUSBFreq) / 1 = 48MHz cusb := clks.clock(clkUSB) cusb.configure(0, // No GLMUX rp.CLOCKS_CLK_USB_CTRL_AUXSRC_CLKSRC_PLL_USB, - pllUSBFreq, - pllUSBFreq) + clockCfg.pllUSBFreq, + clockCfg.pllUSBFreq) // clkADC = pllUSB (pllUSBFreq) / 1 = 48MHz cadc := clks.clock(clkADC) cadc.configure(0, // No GLMUX rp.CLOCKS_CLK_ADC_CTRL_AUXSRC_CLKSRC_PLL_USB, - pllUSBFreq, - pllUSBFreq) + clockCfg.pllUSBFreq, + clockCfg.pllUSBFreq) clks.initRTC() @@ -209,6 +223,6 @@ func (clks *clocksType) init() { cperi := clks.clock(clkPeri) cperi.configure(0, rp.CLOCKS_CLK_PERI_CTRL_AUXSRC_CLK_SYS, - pllSysFreq, - pllSysFreq) + clockCfg.pllSysFreq, + clockCfg.pllSysFreq) } diff --git a/src/machine/machine_rp2_i2c.go b/src/machine/machine_rp2_i2c.go index cf267eac67..98a7c8bc47 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 := pllSysFreq + freqin := clockCfg.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_pll.go b/src/machine/machine_rp2_pll.go index f409768ab3..df7e66fc7a 100644 --- a/src/machine/machine_rp2_pll.go +++ b/src/machine/machine_rp2_pll.go @@ -30,7 +30,7 @@ var ( // // Post Divider 2, postDiv2 with range 1-7. func (pll *pll) init(refdiv, vcoFreq, postDiv1, postDiv2 uint32) { - refFreq := xoscFreq / refdiv + refFreq := clockCfg.xoscFreq / refdiv // What are we multiplying the reference clock by to get the vco freq // (The regs are called div, because you divide the vco output and compare it to the refclk) diff --git a/src/machine/machine_rp2_spi.go b/src/machine/machine_rp2_spi.go index 2bacb6e9e0..edf08740d5 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 = pllSysFreq + var freqin uint32 = clockCfg.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 = pllSysFreq + var freqin uint32 = clockCfg.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 93d8d8924f..0ceb27867d 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 * pllSysFreq / br + div := 8 * clockCfg.pllSysFreq / br ibrd := div >> 7 var fbrd uint32 diff --git a/src/machine/machine_rp2_xosc.go b/src/machine/machine_rp2_xosc.go index c9ce58300b..ed23e4fc2b 100644 --- a/src/machine/machine_rp2_xosc.go +++ b/src/machine/machine_rp2_xosc.go @@ -29,13 +29,13 @@ var xosc = (*xoscType)(unsafe.Pointer(rp.XOSC)) // This function will block until the crystal oscillator has stabilised. func (osc *xoscType) init() { // Assumes 1-15 MHz input - if xoscFreq > 15 { + if clockCfg.xoscFreq > 15 { panic("xosc frequency cannot be greater than 15MHz") } osc.ctrl.Set(rp.XOSC_CTRL_FREQ_RANGE_1_15MHZ) // Set xosc startup delay - delay := (((xoscFreq * MHz) / 1000) + 128) / 256 * XOSC_STARTUP_DELAY_MULTIPLIER + delay := (((clockCfg.xoscFreq * MHz) / 1000) + 128) / 256 * XOSC_STARTUP_DELAY_MULTIPLIER osc.startup.Set(uint32(delay)) // Set the enable bit now that we have set freq range and startup delay