Skip to content

Commit

Permalink
Separate PLL config for RP2040 and RP2350
Browse files Browse the repository at this point in the history
  • Loading branch information
cibomahto committed Dec 31, 2024
1 parent 0426a5f commit a79371f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 20 deletions.
15 changes: 14 additions & 1 deletion src/machine/machine_rp2_2040.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}

Expand Down
14 changes: 14 additions & 0 deletions src/machine/machine_rp2_2350.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 15 additions & 15 deletions src/machine/machine_rp2_clocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()

Expand All @@ -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()
}
2 changes: 1 addition & 1 deletion src/machine/machine_rp2_i2c.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/machine/machine_rp2_spi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/machine/machine_rp2_uart.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a79371f

Please sign in to comment.