Skip to content

Commit 1620986

Browse files
majbthrdWren6991
andauthored
move PLL reset code from clocks driver to pll driver (#110)
* move PLL reset code from clocks driver to pll driver * Don't clear PLL PWR/FBDIV after reset as unnecessary. Call out in runtime.c why USB/syscfg aren't reset. Co-authored-by: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Co-authored-by: Luke Wren <wren6991@gmail.com>
1 parent fd16563 commit 1620986

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

src/rp2_common/hardware_clocks/clocks.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include "pico.h"
88
#include "hardware/regs/clocks.h"
99
#include "hardware/platform_defs.h"
10-
#include "hardware/resets.h"
1110
#include "hardware/clocks.h"
1211
#include "hardware/watchdog.h"
1312
#include "hardware/pll.h"
@@ -149,9 +148,6 @@ void clocks_init(void) {
149148
// PLL USB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz
150149
/// \end::pll_settings[]
151150

152-
reset_block(RESETS_RESET_PLL_SYS_BITS | RESETS_RESET_PLL_USB_BITS);
153-
unreset_block_wait(RESETS_RESET_PLL_SYS_BITS | RESETS_RESET_PLL_USB_BITS);
154-
155151
/// \tag::pll_init[]
156152
pll_init(pll_sys, 1, 1500 * MHZ, 6, 2);
157153
pll_init(pll_usb, 1, 480 * MHZ, 5, 2);

src/rp2_common/hardware_pll/pll.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,11 @@
77
// For MHZ definitions etc
88
#include "hardware/clocks.h"
99
#include "hardware/pll.h"
10+
#include "hardware/resets.h"
1011

1112
/// \tag::pll_init_calculations[]
1213
void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2) {
13-
// Turn off PLL in case it is already running
14-
pll->pwr = 0xffffffff;
15-
pll->fbdiv_int = 0;
16-
1714
uint32_t ref_mhz = XOSC_MHZ / refdiv;
18-
pll->cs = refdiv;
1915

2016
// What are we multiplying the reference clock by to get the vco freq
2117
// (The regs are called div, because you divide the vco output and compare it to the refclk)
@@ -34,11 +30,28 @@ void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div
3430
// than postdiv2
3531
assert(post_div2 <= post_div1);
3632

37-
/// \tag::pll_init_finish[]
3833
// Check that reference frequency is no greater than vco / 16
3934
assert(ref_mhz <= (vco_freq / 16));
4035

41-
// Put calculated value into feedback divider
36+
// div1 feeds into div2 so if div1 is 5 and div2 is 2 then you get a divide by 10
37+
uint32_t pdiv = (post_div1 << PLL_PRIM_POSTDIV1_LSB) |
38+
(post_div2 << PLL_PRIM_POSTDIV2_LSB);
39+
40+
/// \tag::pll_init_finish[]
41+
if ((pll->cs & PLL_CS_LOCK_BITS) &&
42+
(refdiv == (pll->cs & PLL_CS_REFDIV_BITS)) &&
43+
(fbdiv == (pll->fbdiv_int & PLL_FBDIV_INT_BITS)) &&
44+
(pdiv == (pll->prim & (PLL_PRIM_POSTDIV1_BITS & PLL_PRIM_POSTDIV2_BITS)))) {
45+
// do not disrupt PLL that is already correctly configured and operating
46+
return;
47+
}
48+
49+
uint32_t pll_reset = (pll_usb_hw == pll) ? RESETS_RESET_PLL_USB_BITS : RESETS_RESET_PLL_SYS_BITS;
50+
reset_block(pll_reset);
51+
unreset_block_wait(pll_reset);
52+
53+
// Load VCO-related dividers before starting VCO
54+
pll->cs = refdiv;
4255
pll->fbdiv_int = fbdiv;
4356

4457
// Turn on PLL
@@ -50,9 +63,7 @@ void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div
5063
// Wait for PLL to lock
5164
while (!(pll->cs & PLL_CS_LOCK_BITS)) tight_loop_contents();
5265

53-
// Set up post dividers - div1 feeds into div2 so if div1 is 5 and div2 is 2 then you get a divide by 10
54-
uint32_t pdiv = (post_div1 << PLL_PRIM_POSTDIV1_LSB) |
55-
(post_div2 << PLL_PRIM_POSTDIV2_LSB);
66+
// Set up post dividers
5667
pll->prim = pdiv;
5768

5869
// Turn on post divider
@@ -63,4 +74,4 @@ void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div
6374
void pll_deinit(PLL pll) {
6475
// todo: Make sure there are no sources running from this pll?
6576
pll->pwr = PLL_PWR_BITS;
66-
}
77+
}

src/rp2_common/pico_runtime/runtime.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,13 @@ void runtime_init(void) {
6363
// Reset all peripherals to put system into a known state,
6464
// - except for QSPI pads and the XIP IO bank, as this is fatal if running from flash
6565
// - and the PLLs, as this is fatal if clock muxing has not been reset on this boot
66+
// - and USB, syscfg, as this disturbs USB-to-SWD on core 1
6667
reset_block(~(
6768
RESETS_RESET_IO_QSPI_BITS |
6869
RESETS_RESET_PADS_QSPI_BITS |
6970
RESETS_RESET_PLL_USB_BITS |
71+
RESETS_RESET_USBCTRL_BITS |
72+
RESETS_RESET_SYSCFG_BITS |
7073
RESETS_RESET_PLL_SYS_BITS
7174
));
7275

0 commit comments

Comments
 (0)