8000 Need to increase PSRQM divider before sysclk increase · earlephilhower/arduino-pico@17a5b08 · GitHub
[go: up one dir, main page]

Skip to content

Commit 17a5b08

Browse files
Need to increase PSRQM divider before sysclk increase
Per datasheet, when incerasing sysclk speed we need to set the qmi clocks first and do a dummy transfer to ensure no invalid speed operations happen on the bus. Handle the logig for this while setting up the overclock.
1 parent ffb6996 commit 17a5b08

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

cores/rp2040/main.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,25 @@ static struct _reent *_impure_ptr1 = nullptr;
8383

8484
extern "C" int main() {
8585
#if (defined(PICO_RP2040) && (F_CPU != 125000000)) || (defined(PICO_RP2350) && (F_CPU != 150000000))
86+
#if defined(RP2350_PSRAM_CS) && (F_CPU > 150000000)
87+
// Need to increase the qmi divider before upping sysclk to ensure we keep the output sck w/in legal bounds
88+
psram_reinit_timing(F_CPU);
89+
// Per datasheet, need to do a dummy access and memory barrier before it takes effect
90+
extern uint8_t __psram_start__;
91+
volatile uint8_t *x = &__psram_start__;
92+
*x ^= 0xff;
93+
*x ^= 0xff;
94+
asm volatile("" ::: "memory");
95+
#endif
8696
set_sys_clock_khz(F_CPU / 1000, true);
87-
#ifdef RP2350_PSRAM_CS
97+
#if defined(RP2350_PSRAM_CS) && (F_CPU < 150000000)
8898
psram_reinit_timing();
99+
// Per datasheet, need to do a dummy access and memory barrier before it takes effect
100+
extern uint8_t __psram_start__;
101+
volatile uint8_t *x = &__psram_start__;
102+
*x ^= 0xff;
103+
*x ^= 0xff;
104+
asm volatile("" ::: "memory");
89105
#endif
90106
#endif
91107

cores/rp2040/psram.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ const uint32_t SFE_PSRAM_MIN_DESELECT_FS = RP2350_PSRAM_MIN_DESELECT_FS;
107107
// If VDD = 3.0 Max Freq is 133 Mhz
108108
const uint32_t SFE_PSRAM_MAX_SCK_HZ = RP2350_PSRAM_MAX_SCK_HZ;
109109

110+
uint32_t pr1() { return SFE_PSRAM_MAX_SCK_HZ; }
110111
// PSRAM SPI command codes
111112
const uint8_t PSRAM_CMD_QUAD_END = 0xF5;
112113
const uint8_t PSRAM_CMD_QUAD_ENABLE = 0x35;
@@ -195,10 +196,7 @@ static size_t __no_inline_not_in_flash_func(get_psram_size)(void) {
195196
///
196197
/// @note This function expects interrupts to be enabled on entry
197198

198-
static void __no_inline_not_in_flash_func(set_psram_timing)(void) {
199-
// Get secs / cycle for the system clock - get before disabling interrupts.
200-
uint32_t sysHz = (uint32_t)clock_get_hz(clk_sys);
201-
199+
static void __no_inline_not_in_flash_func(set_psram_timing)(uint32_t sysHz) {
202200
// Calculate the clock divider - goal to get clock used for PSRAM <= what
203201
// the PSRAM IC can handle - which is defined in SFE_PSRAM_MAX_SCK_HZ
204202
volatile uint8_t clockDivider = (sysHz + SFE_PSRAM_MAX_SCK_HZ - 1) / SFE_PSRAM_MAX_SCK_HZ;
@@ -283,7 +281,7 @@ static void __no_inline_not_in_flash_func(runtime_init_setup_psram)(/*uint32_t p
283281

284282
// check our interrupts and setup the timing
285283
restore_interrupts(intr_stash);
286-
set_psram_timing();
284+
set_psram_timing((uint32_t)clock_get_hz(clk_sys));
287285

288286
// and now stash interrupts again
289287
intr_stash = save_and_disable_interrupts();
@@ -323,8 +321,11 @@ static void __no_inline_not_in_flash_func(runtime_init_setup_psram)(/*uint32_t p
323321
PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_setup_psram, PICO_RUNTIME_INIT_PSRAM);
324322

325323
// update timing -- used if the system clock/timing was changed.
326-
void psram_reinit_timing() {
327-
set_psram_timing();
324+
void psram_reinit_timing(uint32_t hz) {
325+
if (!hz) {
326+
hz = (uint32_t)clock_get_hz(clk_sys);
327+
}
328+
set_psram_timing(hz);
328329
}
329330

330331
static bool __psram_heap_init() {

cores/rp2040/psram.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
#include <Arduino.h>
3333

34-
void psram_reinit_timing();
34+
void psram_reinit_timing(uint32_t hz = 0);
3535
void *__psram_malloc(size_t size);
3636
void __psram_free(void *ptr);
3737
void *__psram_realloc(void *ptr, size_t size);

0 commit comments

Comments
 (0)
0