Skip to content

Commit c7d1625

Browse files
committed
Rejig clock init to prevent overclocking
Now goes through configurations until it finds one under 150MHz
1 parent 013176c commit c7d1625

File tree

3 files changed

+33
-32
lines changed

3 files changed

+33
-32
lines changed

enc_bootloader/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ if (NOT USE_PRECOMPILED)
5050
)
5151

5252
target_compile_definitions(enc_bootloader PRIVATE
53+
# increase startup delay for stability
54+
PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
5355
# use stack guards, as AES variables are written near the stack
5456
PICO_USE_STACK_GUARDS=1
5557
PICO_STACK_SIZE=0x180

enc_bootloader/enc_bootloader.c

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ void runtime_init_clocks(void) {
163163

164164
bi_decl(bi_ptr_int32(0, 0, rosc_div, 2)); // default divider 2
165165
bi_decl(bi_ptr_int32(0, 0, rosc_drive, 0x0000)); // default drives of 0
166-
bi_decl(bi_ptr_int32(0, 0, xosc_mhz, 12)); // xosc freq in MHz
167-
bi_decl(bi_ptr_int32(0, 0, clk_mhz, 150)); // xosc freq in MHz
166+
bi_decl(bi_ptr_int32(0, 0, xosc_hz, 12000000)); // xosc freq in Hz
167+
bi_decl(bi_ptr_int32(0, 0, clk_khz, 150 * KHZ)); // maximum clk_sys freq in KHz
168168

169169
// Bump up ROSC speed to ~90MHz
170170
rosc_hw->freqa = 0; // reset the drive strengths
@@ -185,51 +185,50 @@ void runtime_init_clocks(void) {
185185
ROSC_FREQB_DS7_LSB | ROSC_FREQB_DS6_LSB | ROSC_FREQB_DS5_LSB | ROSC_FREQB_DS4_LSB;
186186

187187
// Calibrate ROSC frequency if XOSC present - otherwise just configure
188-
uint32_t rosc_freq_mhz = 0;
189-
if (xosc_mhz) {
188+
if (xosc_hz) {
190189
xosc_init();
191190
// Switch away from ROSC to avoid overclocking
192191
// CLK_REF = XOSC
193192
clock_configure_int_divider(clk_ref,
194193
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC,
195194
0,
196-
xosc_mhz * MHZ,
195+
xosc_hz,
197196
1);
198197
// CLK_SYS = CLK_REF
199198
clock_configure_int_divider(clk_sys,
200199
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF,
201200
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC, // leave the aux source on ROSC to prevent glitches when we switch back to it
202-
xosc_mhz * MHZ,
201+
xosc_hz,
203202
1);
204203

205-
// Max out rosc now we've switched away from it
206-
rosc_hw->div = 1 | ROSC_DIV_VALUE_PASS;
207-
rosc_hw->freqa = (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB) |
208-
ROSC_FREQA_DS3_BITS | ROSC_FREQA_DS2_BITS | // maximum drive
209-
ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS; // enable randomisation
210-
211-
// Wait for ROSC to be stable
212-
while(!(rosc_hw->status & ROSC_STATUS_STABLE_BITS)) {
213-
tight_loop_contents();
204+
// Go through configurations until you get below 150MHz
205+
uint8_t div = 1;
206+
uint32_t drives = 0x7777;
207+
while (div < 4) {
208+
rosc_hw->div = div | ROSC_DIV_VALUE_PASS;
209+
rosc_hw->freqa = (ROSC_FREQA_PASSWD_VALUE_PASS << ROSC_FREQA_PASSWD_LSB) |
210+
drives |
211+
ROSC_FREQA_DS1_RANDOM_BITS | ROSC_FREQA_DS0_RANDOM_BITS; // enable randomisation
212+
213+
// Wait for ROSC to be stable
214+
while(!(rosc_hw->status & ROSC_STATUS_STABLE_BITS)) {
215+
tight_loop_contents();
216+
}
217+
218+
if (frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH) < clk_khz) {
219+
break;
220+
}
221+
222+
if (!drives) div++;
223+
drives = drives ? 0x0000 : 0x7777;
214224
}
215-
216-
rosc_freq_mhz = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH) / KHZ;
217-
}
218-
if (rosc_freq_mhz > clk_mhz) {
219-
// CLK SYS = ROSC divided down to clk_mhz, according to XOSC calibration
220-
clock_configure_mhz(clk_sys,
221-
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
222-
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC,
223-
rosc_freq_mhz,
224-
clk_mhz);
225-
} else { // Either ROSC is running too slowly, or there was no XOSC to calibrate it against
226-
// CLK SYS = ROSC directly, as it's running slowly enough
227-
clock_configure_int_divider(clk_sys,
228-
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
229-
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC,
230-
ROSC_HZ, // this doesn't have to be accurate
231-
1);
232225
}
226+
// CLK SYS = ROSC directly, as it's running slowly enough
227+
clock_configure_int_divider(clk_sys,
228+
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
229+
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC,
230+
ROSC_HZ, // this doesn't have to be accurate
231+
1);
233232

234233
// Configure other clocks - none of these need to be accurate
235234

enc_bootloader/enc_bootloader.elf

-360 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)