8000 rp2/clocks_extra: Implement custom clocks_init function. · micropython/micropython@5dcffb5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5dcffb5

Browse files
committed
rp2/clocks_extra: Implement custom clocks_init function.
Adapts pico-sdk clocks_init() into clocks_init_optional_usb() which takes an argument to initialise USB clocks or not. To avoid a code size increase the SDK clocks_init() function is linker wrapped to become clocks_init_optional_usb(true). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent cfa55b4 commit 5dcffb5

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ used during the build process and is not part of the compiled source code.
7373
/ppp_set_auth.* (Apache-2.0)
7474
/rp2
7575
/mutex_extra.c (BSD-3-clause)
76+
/clocks_extra.c (BSD-3-clause)
7677
/stm32
7778
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
7879
/stm32_it.* (MIT + BSD-3-clause)

ports/rp2/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ set(MICROPY_SOURCE_DRIVERS
117117
)
118118

119119
set(MICROPY_SOURCE_PORT
120+
clocks_extra.c
120121
fatfs_port.c
121122
help.c
122123
machine_bitstream.c
@@ -453,6 +454,7 @@ target_compile_options(${MICROPY_TARGET} PRIVATE
453454
target_link_options(${MICROPY_TARGET} PRIVATE
454455
-Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE}
455456
-Wl,--wrap=dcd_event_handler
457+
-Wl,--wrap=clocks_init
456458
)
457459

458460
# Apply optimisations to performance-critical source code.

ports/rp2/clocks_extra.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
#include "pico.h"
7+
#include "clocks_extra.h"
8+
#include "hardware/regs/clocks.h"
9+
#include "hardware/platform_defs.h"
10+
#include "hardware/clocks.h"
11+
#include "hardware/watchdog.h"
12+
#include "hardware/pll.h"
13+
#include "hardware/xosc.h"
14+
#include "hardware/irq.h"
15+
#include "hardware/gpio.h"
16+
17+
#define RTC_CLOCK_FREQ_HZ (USB_CLK_KHZ * KHZ / 1024)
18+
19+
// Wrap the SDK's clocks_init() function to save code size
20+
void __wrap_clocks_init(void) {
21+
clocks_init_optional_usb(true);
22+
}
23+
24+
// Copy of clocks_init() from pico-sdk, with USB
25+
// PLL and clock init made optional (for light sleep wakeup).
26+
void clocks_init_optional_usb(bool init_usb) {
27+
// Start tick in watchdog, the argument is in 'cycles per microsecond' i.e. MHz
28+
watchdog_start_tick(XOSC_KHZ / KHZ);
29+
30+
// Modification: removed FPGA check here
31+
32+
// Disable resus that may be enabled from previous software
33+
clocks_hw->resus.ctrl = 0;
34+
35+
// Enable the xosc
36+
xosc_init();
37+
38+
// Before we touch PLLs, switch sys and ref cleanly away from their aux sources.
39+
hw_clear_bits(&clocks_hw->clk[clk_sys].ctrl, CLOCKS_CLK_SYS_CTRL_SRC_BITS);
40+
while (clocks_hw->clk[clk_sys].selected != 0x1) {
41+
tight_loop_contents();
42+
}
43+
hw_clear_bits(&clocks_hw->clk[clk_ref].ctrl, CLOCKS_CLK_REF_CTRL_SRC_BITS);
44+
while (clocks_hw->clk[clk_ref].selected != 0x1) {
45+
tight_loop_contents();
46+
}
47+
48+
/// \tag::pll_init[]
49+
pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_KHZ * KHZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
50+
if (init_usb) {
51+
pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_KHZ * KHZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2);
52+
}
53+
/// \end::pll_init[]
54+
55+
// Configure clocks
56+
// CLK_REF = XOSC (usually) 12MHz / 1 = 12MHz
57+
clock_configure(clk_ref,
58+
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC,
59+
0, // No aux mux
60+
XOSC_KHZ * KHZ,
61+
XOSC_KHZ * KHZ);
62+
63+
/// \tag::configure_clk_sys[]
64+
// CLK SYS = PLL SYS (usually) 125MHz / 1 = 125MHz
65+
clock_configure(clk_sys,
66+
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
67+
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
68+
SYS_CLK_KHZ * KHZ,
69+
SYS_CLK_KHZ * KHZ);
70+
/// \end::configure_clk_sys[]
71+
72+
if (init_usb) {
73+
// CLK USB = PLL USB 48MHz / 1 = 48MHz
74+
clock_configure(clk_usb,
75+
0, // No GLMUX
76+
CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
77+
USB_CLK_KHZ * KHZ,
78+
USB_CLK_KHZ * KHZ);
79+
}
80+
81+
// CLK ADC = PLL USB 48MHZ / 1 = 48MHz
82+
clock_configure(clk_adc,
83+
0, // No GLMUX
84+
CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CL A8C6 KSRC_PLL_USB,
85+
USB_CLK_KHZ * KHZ,
86+
USB_CLK_KHZ * KHZ);
87+
88+
// CLK RTC = PLL USB 48MHz / 1024 = 46875Hz
89+
clock_configure(clk_rtc,
90+
0, // No GLMUX
91+
CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
92+
USB_CLK_KHZ * KHZ,
93+
RTC_CLOCK_FREQ_HZ);
94+
95+
// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
96+
// Normally choose clk_sys or clk_usb
97+
clock_configure(clk_peri,
98+
0,
99+
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
100+
SYS_CLK_KHZ * KHZ,
101+
SYS_CLK_KHZ * KHZ);
102+
}

ports/rp2/clocks_extra.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2024 Angus Gratton
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
#ifndef MICROPY_INCLUDED_RP2_CLOCKS_EXTRA_H
27+
#define MICROPY_INCLUDED_RP2_CLOCKS_EXTRA_H
28+
29+
#include "hardware/clocks.h"
30+
31+
void clocks_init_optional_usb(bool init_usb);
32+
33+
#endif // MICROPY_INCLUDED_RP2_CLOCKS_EXTRA_H

0 commit comments

Comments
 (0)
0