🛠 Overclocker le RP2040 à 200 MHz (et au-delà) en toute connaissance
Objectifs
La fiche signalétique du RP2040 annonce 133 MHz nominaux, mais la datasheet documente un mode étendu : jusqu'à 200 MHz en sur-alimentant le cœur à 1,15 V via le bit over_vrange du VREG (RP2040 datasheet, §2.15.3 Overclocking ; confirmé publiquement par Raspberry Pi, voir aussi le débat de doc pico-feedback#499). La puce dispose même d'un ROSC auto-tuné qui adapte la tension interne au silicium (§2.15.2). Ce tuto : monter à 200 MHz proprement, le prouver par un benchmark, et connaître les limites (flash QSPI, thermique, variabilité).
Matériel
- 1 × carte RP2040 générique (les clones à régulateur bas de gamme chauffent plus : vise d'abord une carte connue, Waveshare/Adafruit)
- Pico SDK (C), cible liée avec
pico_stdlib hardware_vreg hardware_clocks - Optionnel : refroidissement modeste (dissipateur, souffle d'air) pour les essais > 200 MHz
Code complet
// oc200.c — 200 MHz avec VREG forcé, benchmark Dhrystone-like
#include "pico/stdlib.h"
#include "hardware/vreg.h"
#include "hardware/clocks.h"
int main(void) {
stdio_init_all;
// 1) monter la tension du cœur AVANT la fréquence (datasheet 2.15.3)
vreg_set_voltage(VREG_VOLTAGE_1_20); // 1,20 V > nominal 1,10 V
sleep_ms(10); // laisser le régulateur stabiliser
// 2) demander 200 MHz au PLL (le SDK rebascule sur XOSC si besoin)
set_sys_clock_khz(200000, true);
printf("clk_sys = %lu Hz\n", clock_get_hz(clk_sys));
// 3) benchmark : boucle dépendante, sans FPU (le M0+ n'en a pas)
uint32_t t0 = time_us_32;
volatile uint32_t x = 0;
for (uint32_t i = 0; i < 1000000; i++) { x = x * 1664525u + 1013904223u; }
uint32_t dt = time_us_32 - t0;
printf("1e6 iters en %lu us (x=%lu)\n", dt, x);
while (true) { sleep_ms(1000); } // laisse la puce « au ralenti »
}
Vérification attendue
clk_sys = 200000000 s'affiche, et le temps du benchmark baisse d'environ 1,6× par rapport au run à 125/133 MHz (le ratio exact dépend du code et de l'attente flash). La puce tiendra à 200 MHz sur une carte correcte — c'est la fréquence certifiée « over_vrange » de la datasheet. Pour t'affranchir de la variabilité silicium, le SDK propose le réglage automatique par ROSC (set_sys_clock_khz + mode autotune utilisé par l'exemple sys_clk400 de pico-extras) — MicroPython documente d'ailleurs des dépassements au-delà de 400 MHz sur des puces chanceuses (docs rp2).
Erreurs fréquentes
- Monter la fréquence avant la tension : le cœur devient instable, plantages aléatoires — l'ordre VREG → PLL est contractuel.
- Oublier que le XOSC doit rester la source au-delà de 150 MHz : le SDK le gère (
set_sys_clock_khzrebascule clk_ref), mais un clocking manuel qui laisse le ROSC à 6,4 MHz en maître plante tout. - Négliger la flash QSPI : à 200 MHz, les délais flash (clock de la QSPI, mode XIP) doivent suivre — le SDK réduit le clock QSPI automatiquement, un clocking maison non.
- Croire que tous les clones tiennent : les régulateurs et la qualité des clones varient ; en dessous de 1,2 V ou sur un clone douteux, 200 MHz peut être instable — teste par de longues boucles (le benchmark ci-dessus tourne des millions d'itérations, les erreurs LCG se voient).
- L'overclocking annule la garantie et n'est pas couvert par le caractéristage Raspberry Pi au-delà des valeurs datasheet — considère-le comme du tuning.
- Alimenter par un hub USB faible : à 200 MHz la conso monte (ordres de grandeur : dizaines de mA de plus), un brown-out ressemble à un bug d'overclocking.
- Comparer des benchmarks sans désactiver les mêmes périphériques : l'USB, le DMA et le bus AHB partagé faussent les mesures — fixe une méthode avant de comparer 133 vs 200 MHz.
Autres tutoriels pour cette carte
- Piloter la LED RGB embarquée WS2812 d'une carte RP2040 générique
- Avoir une console série sur une carte sans pont USB (UART0)
- Jouer une mélodie avec un buzzer passif et le PWM
- Afficher sur un OLED I2C SSD1306 et déboguer le bus
- Logger sur carte microSD en SPI (mode carte)
- Interruptions GPIO et alarmes matérielles avec le Pico SDK
Exemples de code pour cette carte
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython