Skip to content

fix: solve the problem that the flash clock frequency is too high and… #17374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

Lesords
Copy link
Contributor

@Lesords Lesords commented May 28, 2025

Summary

Reduce the flash clock frequency to avoid the problem of XIAO RP2350 not responding and having no serial port after flashing the firmware.

Testing

Tested on XIAO RP2350

@Lesords
Copy link
Contributor Author

Lesords commented May 28, 2025

You can get more information through this issue: #17375

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

Signed-off-by: Lesords <lesords168@gmail.com>
@Lesords
Copy link
Contributor Author

Lesords commented May 28, 2025

Forgive me for making so many changes, all to get past the commit format checking

@peterhinch
Copy link
Contributor

From the code comments it seems this is an issue with Winbond external SPI flash. If different manufacturers use Flash chips with different maximum clock rates should this be a board-specific build option?

@Lesords
Copy link
Contributor Author

Lesords commented May 28, 2025

From the code comments it seems this is an issue with Winbond external SPI flash. If different manufacturers use Flash chips with different maximum clock rates should this be a board-specific build option?

You can check this issue:#17375

Previously, PICO could modify the flash clock frequency based on this macro PICO_FLASH_SPI_CLKDIV

@Lesords
Copy link
Contributor Author

Lesords commented May 28, 2025

Before this commit 91cff8e, everything was working fine.

@Gadgetoid
Copy link
Contributor

Gadgetoid commented May 29, 2025

Looks like the linked commit - which entered the codebase via the PSRAM changes IIRC - does indeed ignore PICO_FLASH_SPI_CLKDIV. This is very much an unintended consequence.

The normal flash speed is clock_sys / PICO_FLASH_SPI_CLKDIV which in the case of XIAO RP2350 puts it at 33.25MHz at the stock 133MHz clock (though with the RP2040 now certified to run at 200MHz the dividers are all, effectively, kinda wrong.).

Looks like the formula should be something like int max_flash_freq = 133000000 / PICO_FLASH_SPI_CLKDIV, which would pick the safest maximum frequency in all cases.

Ideally it would be int max_flash_freq = 266000000 / PICO_FLASH_SPI_CLKDIV for the most aggressive speed, since we're otherwise leaving performance on the table.

Pico SDK is weird in that PICO_FLASH_SPI_CLKDIV isn't very useful for MicroPython. It should ideally be PICO_FLASH_SPI_FREQ. The divider should be worked out automatically depending on the current system clock. I don't think Pico SDK's designers had use cases like MicroPython in mind where the clock frequency might change at runtime. It's somewhat left as an exercise to the user to pick a clock speed and tweak the divider.

I suggest we make this value a board configuration option that defaults to 133000000 / PICO_FLASH_SPI_CLKDIV. In XAIO's case that would be 33.25MHz but they could then (optionally) set that to 60MHz (as evidenced by the changes in this PR) for a performance boost.

--

Edit: Sorry RP2040's clocks are 125MHz or 200MHz: https://github.com/raspberrypi/pico-sdk/blob/ee68c78d0afae2b69c03ae1a72bf5cc267a2d94c/src/rp2040/hardware_regs/include/hardware/platform_defs.h#L76-L80

(afaik there's no accounting for flash divider here?)

And RP2350 is 150MHz.

@nspsck
Copy link
Contributor

nspsck commented May 31, 2025

I think a cleaner approach would be something like:

  // Use the minimum divisor assuming a 133MHz flash.
#ifdef WAVESHARE_RP2350_ZERO
  const int max_flash_freq = 60000000;
#else
  const int max_flash_freq = 133000000;
#endif

Then we would just add boards to

#ifdef WAVESHARE_RP2350_ZERO

And whenever we add a board that is officially supported by pico-sdk, we should be adding something like this to mpconfigboard.cmake:

set(PICO_BOARD "waveshare_rp2350_zero")

@nspsck
Copy link
Contributor

nspsck commented May 31, 2025

I think a cleaner approach would be something like:

  // Use the minimum divisor assuming a 133MHz flash.
#ifdef WAVESHARE_RP2350_ZERO
  const int max_flash_freq = 60000000;
#else
  const int max_flash_freq = 133000000;
#endif

Then we would just add boards to

#ifdef WAVESHARE_RP2350_ZERO

And whenever we add a board that is officially supported by pico-sdk, we should be adding something like this to mpconfigboard.cmake:

set(PICO_BOARD "waveshare_rp2350_zero")

Nvm, something better, assuming pico-sdk will not have something like spi clkdiv = 5 or so:

  // Use the minimum divisor assuming a 133MHz flash.
  const int max_flash_freq = 133000000;
  int divisor = (clock_hz + max_flash_freq - 1) / max_flash_freq;

  // For boards with PICO_FLASH_SPI_CLKDIV = 3
#if PICO_FLASH_SPI_CLKDIV == 3
  divisor++;
#endif

  // For boards with PICO_FLASH_SPI_CLKDIV = 4
#if PICO_FLASH_SPI_CLKDIV == 4
  divisor += 2;
#endif

or a little harder to read, but more future proof

  // Use the minimum divisor assuming a 133MHz flash.
  const int max_flash_freq = 133000000;
  int divisor = (clock_hz + max_flash_freq - 1) / max_flash_freq + PICO_FLASH_SPI_CLKDIV - 2;

This should cover all future problems with other vendors boards, if pico-sdk supports their boards. And this results higher flash speed in almost all sense making cases.

@dpgeorge
Copy link
Member

This definitely needs to be fixed.

It looks like PICO_FLASH_SPI_CLKDIV is only used by the stage 2 bootloader. And it defaults to 4. Boards that have defined this usually define it to 2 to increase performance of the SPI flash.

I suggest we make this value a board configuration option that defaults to 133000000 / PICO_FLASH_SPI_CLKDIV.

Yes, I think this is the right approach. So a board would define something like:

#define MICROPY_HW_SPIFLASH_MAX_FREQ (133000000)

and it would default to:

#ifndef MICROPY_HW_SPIFLASH_MAX_FREQ
#if PICO_RP2040
#define MICROPY_HW_SPIFLASH_MAX_FREQ (125000000 / PICO_FLASH_SPI_CLKDIV)
#else
#define MICROPY_HW_SPIFLASH_MAX_FREQ (150000000 / PICO_FLASH_SPI_CLKDIV)
#endif
#endif

@dpgeorge dpgeorge added this to the release-1.26.0 milestone Jun 16, 2025
@Gadgetoid
Copy link
Contributor

Yes, I think this is the right approach. So a board would define something like:

Basically what I've done here: #17389

MICROPY_HW_SPIFLASH_MAX_FREQ might be a more explicit name for the variable, though!

@dpgeorge
Copy link
Member

Basically what I've done here: #17389

Ah, sorry, I missed that!

Let's close this PR then, in favour of that one.

@dpgeorge dpgeorge closed this Jun 16, 2025
@Gadgetoid
Copy link
Contributor

Ah, sorry, I missed that!

No worries, if you're coming up with basically the same fix then I can't have gone far wrong... y'know apart from adopting the change that broke this in the first place 😆

@dpgeorge
Copy link
Member

y'know apart from adopting the change that broke this in the first place

Haha, indeed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy