diff options
| -rw-r--r-- | embassy-rp/src/clocks.rs | 324 | ||||
| -rw-r--r-- | examples/rp/src/bin/overclock.rs | 11 | ||||
| -rw-r--r-- | examples/rp/src/bin/overclock_manual.rs | 20 | ||||
| -rw-r--r-- | tests/rp/src/bin/overclock.rs | 10 |
4 files changed, 134 insertions, 231 deletions
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs index 005564b8b..107e499b7 100644 --- a/embassy-rp/src/clocks.rs +++ b/embassy-rp/src/clocks.rs | |||
| @@ -9,9 +9,8 @@ | |||
| 9 | //! | 9 | //! |
| 10 | //! For most users, these functions provide an easy way to configure clocks: | 10 | //! For most users, these functions provide an easy way to configure clocks: |
| 11 | //! | 11 | //! |
| 12 | //! - `ClockConfig::crystal(12_000_000)` - Default configuration with 12MHz crystal giving 125MHz system clock | ||
| 13 | //! - `ClockConfig::at_sys_frequency_mhz(200)` - Set system clock to a specific frequency with automatic voltage scaling | 12 | //! - `ClockConfig::at_sys_frequency_mhz(200)` - Set system clock to a specific frequency with automatic voltage scaling |
| 14 | //! - `ClockConfig::with_external_crystal(16_000_000)` - Configure with a non-standard crystal frequency | 13 | //! - `ClockConfig::crystal(12_000_000)` - Default configuration with 12MHz crystal giving 125MHz system clock |
| 15 | //! | 14 | //! |
| 16 | //! ## Manual Configuration | 15 | //! ## Manual Configuration |
| 17 | //! | 16 | //! |
| @@ -34,19 +33,9 @@ | |||
| 34 | //! }); | 33 | //! }); |
| 35 | //! | 34 | //! |
| 36 | //! // Set voltage for overclocking | 35 | //! // Set voltage for overclocking |
| 37 | //! config.voltage_scale = Some(VoltageScale::V1_15); | 36 | //! config.core_voltage = CoreVoltage::V1_15; |
| 38 | //! ``` | 37 | //! ``` |
| 39 | //! | 38 | //! |
| 40 | //! ## Voltage Scaling for Overclocking (RP2040 only) | ||
| 41 | //! | ||
| 42 | //! When overclocking beyond 133MHz, higher core voltages are needed: | ||
| 43 | //! | ||
| 44 | //! - Up to 133MHz: `VoltageScale::V1_10` (default) | ||
| 45 | //! - 133-200MHz: `VoltageScale::V1_15` | ||
| 46 | //! - Above 200MHz: `VoltageScale::V1_20` or higher | ||
| 47 | //! | ||
| 48 | //! The `at_sys_frequency_mhz()` function automatically sets appropriate voltages. | ||
| 49 | //! | ||
| 50 | //! ## Examples | 39 | //! ## Examples |
| 51 | //! | 40 | //! |
| 52 | //! ### Standard 125MHz configuration | 41 | //! ### Standard 125MHz configuration |
| @@ -61,16 +50,16 @@ | |||
| 61 | //! | 50 | //! |
| 62 | //! ### Overclock to 200MHz | 51 | //! ### Overclock to 200MHz |
| 63 | //! ```rust,ignore | 52 | //! ```rust,ignore |
| 64 | //! let config = ClockConfig::at_sys_frequency_mhz(200); | 53 | //! let config = ClockConfig::crystal_freq(200_000_000); |
| 65 | //! ``` | 54 | //! ``` |
| 66 | //! | 55 | //! |
| 67 | //! ### Manual configuration for advanced scenarios | 56 | //! ### Manual configuration for advanced scenarios |
| 68 | //! ```rust,ignore | 57 | //! ```rust,ignore |
| 69 | //! use embassy_rp::clocks::{ClockConfig, XoscConfig, PllConfig, VoltageScale}; | 58 | //! use embassy_rp::clocks::{ClockConfig, XoscConfig, PllConfig, CoreVoltage}; |
| 70 | //! | 59 | //! |
| 71 | //! // Start with defaults and customize | 60 | //! // Start with defaults and customize |
| 72 | //! let mut config = ClockConfig::default(); | 61 | //! let mut config = ClockConfig::default(); |
| 73 | //! config.voltage_scale = Some(VoltageScale::V1_15); | 62 | //! config.core_voltage = CoreVoltage::V1_15; |
| 74 | //! // Set other parameters as needed... | 63 | //! // Set other parameters as needed... |
| 75 | //! ``` | 64 | //! ``` |
| 76 | 65 | ||
| @@ -144,14 +133,16 @@ pub enum PeriClkSrc { | |||
| 144 | // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ , | 133 | // Gpin1 = ClkPeriCtrlAuxsrc::CLKSRC_GPIN1 as _ , |
| 145 | } | 134 | } |
| 146 | 135 | ||
| 147 | /// Core voltage scaling options for RP2040. | 136 | /// Core voltage regulator settings for RP2040. |
| 148 | /// | 137 | /// |
| 149 | /// The RP2040 voltage regulator can be configured for different output voltages. | 138 | /// The RP2040 voltage regulator can be configured for different output voltages. |
| 150 | /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. | 139 | /// Higher voltages allow for higher clock frequencies but increase power consumption and heat. |
| 151 | #[cfg(feature = "rp2040")] | 140 | #[cfg(feature = "rp2040")] |
| 152 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | 141 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 153 | #[repr(u8)] | 142 | #[repr(u8)] |
| 154 | pub enum VoltageScale { | 143 | pub enum CoreVoltage { |
| 144 | /// 0.80V - Suitable for lower frequencies | ||
| 145 | V0_80 = 0b0000, | ||
| 155 | /// 0.85V | 146 | /// 0.85V |
| 156 | V0_85 = 0b0110, | 147 | V0_85 = 0b0110, |
| 157 | /// 0.90V | 148 | /// 0.90V |
| @@ -162,11 +153,11 @@ pub enum VoltageScale { | |||
| 162 | V1_00 = 0b1001, | 153 | V1_00 = 0b1001, |
| 163 | /// 1.05V | 154 | /// 1.05V |
| 164 | V1_05 = 0b1010, | 155 | V1_05 = 0b1010, |
| 165 | /// 1.10V | 156 | /// 1.10V - Default voltage level |
| 166 | V1_10 = 0b1011, | 157 | V1_10 = 0b1011, |
| 167 | /// 1.15V | 158 | /// 1.15V - Required for overclocking to 133-200MHz |
| 168 | V1_15 = 0b1100, | 159 | V1_15 = 0b1100, |
| 169 | /// 1.20V | 160 | /// 1.20V - Required for overclocking above 200MHz |
| 170 | V1_20 = 0b1101, | 161 | V1_20 = 0b1101, |
| 171 | /// 1.25V | 162 | /// 1.25V |
| 172 | V1_25 = 0b1110, | 163 | V1_25 = 0b1110, |
| @@ -175,21 +166,22 @@ pub enum VoltageScale { | |||
| 175 | } | 166 | } |
| 176 | 167 | ||
| 177 | #[cfg(feature = "rp2040")] | 168 | #[cfg(feature = "rp2040")] |
| 178 | impl VoltageScale { | 169 | impl CoreVoltage { |
| 179 | /// Get the recommended Brown-Out Detection (BOD) setting for this voltage. | 170 | /// Get the recommended Brown-Out Detection (BOD) setting for this voltage. |
| 180 | /// Sets the BOD threshold to approximately 90% of the core voltage. | 171 | /// Sets the BOD threshold to approximately 90% of the core voltage. |
| 181 | fn recommended_bod(self) -> u8 { | 172 | fn recommended_bod(self) -> u8 { |
| 182 | match self { | 173 | match self { |
| 183 | VoltageScale::V0_85 => 0b0111, // 0.774V (~91% of 0.85V) | 174 | CoreVoltage::V0_80 => 0b0110, // 0.720V (~90% of 0.80V) |
| 184 | VoltageScale::V0_90 => 0b1000, // 0.817V (~91% of 0.90V) | 175 | CoreVoltage::V0_85 => 0b0111, // 0.774V (~91% of 0.85V) |
| 185 | VoltageScale::V0_95 => 0b1001, // 0.860V (~91% of 0.95V) | 176 | CoreVoltage::V0_90 => 0b1000, // 0.817V (~91% of 0.90V) |
| 186 | VoltageScale::V1_00 => 0b1010, // 0.903V (~90% of 1.00V) | 177 | CoreVoltage::V0_95 => 0b1001, // 0.860V (~91% of 0.95V) |
| 187 | VoltageScale::V1_05 => 0b1011, // 0.946V (~90% of 1.05V) | 178 | CoreVoltage::V1_00 => 0b1010, // 0.903V (~90% of 1.00V) |
| 188 | VoltageScale::V1_10 => 0b1100, // 0.989V (~90% of 1.10V) | 179 | CoreVoltage::V1_05 => 0b1011, // 0.946V (~90% of 1.05V) |
| 189 | VoltageScale::V1_15 => 0b1101, // 1.032V (~90% of 1.15V) | 180 | CoreVoltage::V1_10 => 0b1100, // 0.989V (~90% of 1.10V) |
| 190 | VoltageScale::V1_20 => 0b1110, // 1.075V (~90% of 1.20V) | 181 | CoreVoltage::V1_15 => 0b1101, // 1.032V (~90% of 1.15V) |
| 191 | VoltageScale::V1_25 => 0b1111, // 1.118V (~89% of 1.25V) | 182 | CoreVoltage::V1_20 => 0b1110, // 1.075V (~90% of 1.20V) |
| 192 | VoltageScale::V1_30 => 0b1111, // 1.118V (~86% of 1.30V) - using max available threshold | 183 | CoreVoltage::V1_25 => 0b1111, // 1.118V (~89% of 1.25V) |
| 184 | CoreVoltage::V1_30 => 0b1111, // 1.118V (~86% of 1.30V) - using max available threshold | ||
| 193 | } | 185 | } |
| 194 | } | 186 | } |
| 195 | } | 187 | } |
| @@ -214,9 +206,9 @@ pub struct ClockConfig { | |||
| 214 | /// RTC clock configuration. | 206 | /// RTC clock configuration. |
| 215 | #[cfg(feature = "rp2040")] | 207 | #[cfg(feature = "rp2040")] |
| 216 | pub rtc_clk: Option<RtcClkConfig>, | 208 | pub rtc_clk: Option<RtcClkConfig>, |
| 217 | /// Core voltage scaling (RP2040 only). Defaults to 1.10V if None. | 209 | /// Core voltage scaling (RP2040 only). Defaults to 1.10V. |
| 218 | #[cfg(feature = "rp2040")] | 210 | #[cfg(feature = "rp2040")] |
| 219 | pub voltage_scale: Option<VoltageScale>, | 211 | pub core_voltage: CoreVoltage, |
| 220 | /// Voltage stabilization delay in microseconds. | 212 | /// Voltage stabilization delay in microseconds. |
| 221 | /// If not set, defaults will be used based on voltage level. | 213 | /// If not set, defaults will be used based on voltage level. |
| 222 | #[cfg(feature = "rp2040")] | 214 | #[cfg(feature = "rp2040")] |
| @@ -255,7 +247,7 @@ impl Default for ClockConfig { | |||
| 255 | #[cfg(feature = "rp2040")] | 247 | #[cfg(feature = "rp2040")] |
| 256 | rtc_clk: None, | 248 | rtc_clk: None, |
| 257 | #[cfg(feature = "rp2040")] | 249 | #[cfg(feature = "rp2040")] |
| 258 | voltage_scale: None, | 250 | core_voltage: CoreVoltage::V1_10, |
| 259 | #[cfg(feature = "rp2040")] | 251 | #[cfg(feature = "rp2040")] |
| 260 | voltage_stabilization_delay_us: None, | 252 | voltage_stabilization_delay_us: None, |
| 261 | // gpin0: None, | 253 | // gpin0: None, |
| @@ -327,7 +319,7 @@ impl ClockConfig { | |||
| 327 | phase: 0, | 319 | phase: 0, |
| 328 | }), | 320 | }), |
| 329 | #[cfg(feature = "rp2040")] | 321 | #[cfg(feature = "rp2040")] |
| 330 | voltage_scale: None, // Use hardware default (1.10V) | 322 | core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V) |
| 331 | #[cfg(feature = "rp2040")] | 323 | #[cfg(feature = "rp2040")] |
| 332 | voltage_stabilization_delay_us: None, | 324 | voltage_stabilization_delay_us: None, |
| 333 | // gpin0: None, | 325 | // gpin0: None, |
| @@ -371,7 +363,7 @@ impl ClockConfig { | |||
| 371 | phase: 0, | 363 | phase: 0, |
| 372 | }), | 364 | }), |
| 373 | #[cfg(feature = "rp2040")] | 365 | #[cfg(feature = "rp2040")] |
| 374 | voltage_scale: None, // Use hardware default (1.10V) | 366 | core_voltage: CoreVoltage::V1_10, // Use hardware default (1.10V) |
| 375 | #[cfg(feature = "rp2040")] | 367 | #[cfg(feature = "rp2040")] |
| 376 | voltage_stabilization_delay_us: None, | 368 | voltage_stabilization_delay_us: None, |
| 377 | // gpin0: None, | 369 | // gpin0: None, |
| @@ -379,146 +371,59 @@ impl ClockConfig { | |||
| 379 | } | 371 | } |
| 380 | } | 372 | } |
| 381 | 373 | ||
| 382 | /// Configure the system clock to a specific frequency in MHz. | ||
| 383 | /// | ||
| 384 | /// This is a user-friendly way to configure the system clock, similar to | ||
| 385 | /// the Pico SDK's approach. It automatically handles voltage scaling based on the | ||
| 386 | /// requested frequency and uses the standard 12MHz crystal found on most RP2040 boards. | ||
| 387 | /// | ||
| 388 | /// # Arguments | ||
| 389 | /// | ||
| 390 | /// * `sys_freq_mhz` - The target system clock frequency in MHz | ||
| 391 | /// | ||
| 392 | /// # Example | ||
| 393 | /// | ||
| 394 | /// ```rust,ignore | ||
| 395 | /// // Overclock to 200MHz | ||
| 396 | /// let config = ClockConfig::at_sys_frequency_mhz(200); | ||
| 397 | /// ``` | ||
| 398 | #[cfg(feature = "rp2040")] | ||
| 399 | pub fn at_sys_frequency_mhz(sys_freq_mhz: u32) -> Self { | ||
| 400 | // For 125MHz, use exactly the same config as the default to avoid any differences | ||
| 401 | if sys_freq_mhz == 125 { | ||
| 402 | return Self::crystal(12_000_000); | ||
| 403 | } | ||
| 404 | |||
| 405 | // For other frequencies, provide appropriate voltage scaling and PLL configuration | ||
| 406 | // Standard crystal on Raspberry Pi Pico boards is 12MHz | ||
| 407 | const DEFAULT_CRYSTAL_HZ: u32 = 12_000_000; | ||
| 408 | |||
| 409 | let sys_freq_hz = sys_freq_mhz * 1_000_000; | ||
| 410 | let config = Self::crystal_freq(DEFAULT_CRYSTAL_HZ, sys_freq_hz); | ||
| 411 | |||
| 412 | config | ||
| 413 | } | ||
| 414 | |||
| 415 | /// Configure the system clock to a specific frequency in Hz, using a custom crystal frequency. | ||
| 416 | /// | ||
| 417 | /// This more flexible version allows specifying both the crystal frequency and target | ||
| 418 | /// system frequency for boards with non-standard crystals. | ||
| 419 | /// | ||
| 420 | /// # Arguments | ||
| 421 | /// | ||
| 422 | /// * `crystal_hz` - The frequency of the external crystal in Hz | ||
| 423 | /// * `sys_freq_hz` - The target system clock frequency in Hz | ||
| 424 | /// | ||
| 425 | /// # Example | ||
| 426 | /// | ||
| 427 | /// ```rust,ignore | ||
| 428 | /// // Use a non-standard 16MHz crystal to achieve 250MHz | ||
| 429 | /// let config = ClockConfig::with_custom_crystal(16_000_000, 250_000_000); | ||
| 430 | /// ``` | ||
| 431 | #[cfg(feature = "rp2040")] | ||
| 432 | pub fn with_custom_crystal(crystal_hz: u32, sys_freq_hz: u32) -> Self { | ||
| 433 | Self::crystal_freq(crystal_hz, sys_freq_hz) | ||
| 434 | } | ||
| 435 | |||
| 436 | /// Configure clocks derived from an external crystal with specific system frequency. | 374 | /// Configure clocks derived from an external crystal with specific system frequency. |
| 437 | /// | 375 | /// |
| 438 | /// This function calculates optimal PLL parameters to achieve the requested system | 376 | /// This function calculates optimal PLL parameters to achieve the requested system |
| 439 | /// frequency from the given crystal frequency. It's used internally by higher-level | 377 | /// frequency. This only works for the usual 12MHz crystal. In case a different crystal is used, |
| 440 | /// configuration functions. | 378 | /// You will have to set the PLL parameters manually. |
| 441 | /// | 379 | /// |
| 442 | /// # Arguments | 380 | /// # Arguments |
| 443 | /// | 381 | /// |
| 444 | /// * `crystal_hz` - The frequency of the external crystal in Hz | ||
| 445 | /// * `sys_freq_hz` - The desired system clock frequency in Hz | 382 | /// * `sys_freq_hz` - The desired system clock frequency in Hz |
| 446 | /// | 383 | /// |
| 447 | /// # Returns | 384 | /// # Returns |
| 448 | /// | 385 | /// |
| 449 | /// A ClockConfig configured to achieve the requested system frequency using the | 386 | /// A ClockConfig configured to achieve the requested system frequency using the |
| 450 | /// specified crystal, or panic if no valid parameters can be found. | 387 | /// the usual 12Mhz crystal, or panic if no valid parameters can be found. |
| 388 | /// | ||
| 389 | /// # Note on core voltage: | ||
| 390 | /// To date the only officially documented core voltages (see Datasheet section 2.15.3.1. Instances) are: | ||
| 391 | /// - Up to 133MHz: V1_10 (default) | ||
| 392 | /// - Above 133MHz: V1_15, but in the context of the datasheet covering reaching up to 200Mhz | ||
| 393 | /// That way all other frequencies below 133MHz or above 200MHz are not explicitly documented and not covered here. | ||
| 394 | /// In case You want to go below 133MHz or above 200MHz and want a different voltage, You will have to set that manually and with caution. | ||
| 451 | #[cfg(feature = "rp2040")] | 395 | #[cfg(feature = "rp2040")] |
| 452 | fn crystal_freq(crystal_hz: u32, sys_freq_hz: u32) -> Self { | 396 | pub fn crystal_freq(sys_freq_hz: u32) -> Self { |
| 397 | // Start with the standard configuration from crystal() | ||
| 398 | const DEFAULT_CRYSTAL_HZ: u32 = 12_000_000; | ||
| 399 | let mut config = Self::crystal(DEFAULT_CRYSTAL_HZ); | ||
| 400 | |||
| 401 | // No need to modify anything if target frequency is already 125MHz | ||
| 402 | // (which is what crystal() configures by default) | ||
| 403 | if sys_freq_hz == 125_000_000 { | ||
| 404 | return config; | ||
| 405 | } | ||
| 406 | |||
| 453 | // Find optimal PLL parameters for the requested frequency | 407 | // Find optimal PLL parameters for the requested frequency |
| 454 | let sys_pll_params = find_pll_params(crystal_hz, sys_freq_hz) | 408 | let sys_pll_params = find_pll_params(DEFAULT_CRYSTAL_HZ, sys_freq_hz) |
| 455 | .unwrap_or_else(|| panic!("Could not find valid PLL parameters for system clock")); | 409 | .unwrap_or_else(|| panic!("Could not find valid PLL parameters for system clock")); |
| 456 | 410 | ||
| 411 | // Replace the sys_pll configuration with our custom parameters | ||
| 412 | if let Some(xosc) = &mut config.xosc { | ||
| 413 | xosc.sys_pll = Some(sys_pll_params); | ||
| 414 | } | ||
| 415 | |||
| 457 | // Set the voltage scale based on the target frequency | 416 | // Set the voltage scale based on the target frequency |
| 458 | // Higher frequencies require higher voltage | 417 | // Higher frequencies require higher voltage |
| 459 | let voltage_scale = match sys_freq_hz { | 418 | #[cfg(feature = "rp2040")] |
| 460 | freq if freq > 200_000_000 => Some(VoltageScale::V1_20), | 419 | { |
| 461 | freq if freq > 133_000_000 => Some(VoltageScale::V1_15), | 420 | config.core_voltage = match sys_freq_hz { |
| 462 | _ => None, // Use default voltage (V1_10) | 421 | freq if freq > 133_000_000 => CoreVoltage::V1_15, |
| 463 | }; | 422 | _ => CoreVoltage::V1_10, // Use default voltage (V1_10) |
| 464 | 423 | }; | |
| 465 | // For USB PLL, we always want 48MHz for USB | ||
| 466 | let usb_pll_params = if crystal_hz == 12_000_000 { | ||
| 467 | // For standard 12MHz crystal, use the default parameters | ||
| 468 | PllConfig { | ||
| 469 | refdiv: 1, | ||
| 470 | fbdiv: 120, | ||
| 471 | post_div1: 6, | ||
| 472 | post_div2: 5, | ||
| 473 | } | ||
| 474 | } else { | ||
| 475 | // For other crystals, calculate parameters to get 48MHz | ||
| 476 | find_pll_params(crystal_hz, 48_000_000) | ||
| 477 | .unwrap_or_else(|| panic!("Could not find valid PLL parameters for USB clock")) | ||
| 478 | }; | ||
| 479 | |||
| 480 | Self { | ||
| 481 | rosc: Some(RoscConfig { | ||
| 482 | hz: 6_500_000, | ||
| 483 | range: RoscRange::Medium, | ||
| 484 | drive_strength: [0; 8], | ||
| 485 | div: 16, | ||
| 486 | }), | ||
| 487 | xosc: Some(XoscConfig { | ||
| 488 | hz: crystal_hz, | ||
| 489 | sys_pll: Some(sys_pll_params), | ||
| 490 | usb_pll: Some(usb_pll_params), | ||
| 491 | delay_multiplier: 128, | ||
| 492 | }), | ||
| 493 | ref_clk: RefClkConfig { | ||
| 494 | src: RefClkSrc::Xosc, | ||
| 495 | div: 1, | ||
| 496 | }, | ||
| 497 | sys_clk: SysClkConfig { | ||
| 498 | src: SysClkSrc::PllSys, | ||
| 499 | div_int: 1, | ||
| 500 | div_frac: 0, | ||
| 501 | }, | ||
| 502 | peri_clk_src: Some(PeriClkSrc::Sys), | ||
| 503 | usb_clk: Some(UsbClkConfig { | ||
| 504 | src: UsbClkSrc::PllUsb, | ||
| 505 | div: 1, | ||
| 506 | phase: 0, | ||
| 507 | }), | ||
| 508 | adc_clk: Some(AdcClkConfig { | ||
| 509 | src: AdcClkSrc::PllUsb, | ||
| 510 | div: 1, | ||
| 511 | phase: 0, | ||
| 512 | }), | ||
| 513 | rtc_clk: Some(RtcClkConfig { | ||
| 514 | src: RtcClkSrc::PllUsb, | ||
| 515 | div_int: 1024, | ||
| 516 | div_frac: 0, | ||
| 517 | phase: 0, | ||
| 518 | }), | ||
| 519 | voltage_scale, | ||
| 520 | voltage_stabilization_delay_us: None, | ||
| 521 | } | 424 | } |
| 425 | |||
| 426 | config | ||
| 522 | } | 427 | } |
| 523 | 428 | ||
| 524 | /// Configure with manual PLL settings for full control over system clock | 429 | /// Configure with manual PLL settings for full control over system clock |
| @@ -530,7 +435,7 @@ impl ClockConfig { | |||
| 530 | /// | 435 | /// |
| 531 | /// * `xosc_hz` - The frequency of the external crystal in Hz | 436 | /// * `xosc_hz` - The frequency of the external crystal in Hz |
| 532 | /// * `pll_config` - The PLL configuration parameters to achieve desired frequency | 437 | /// * `pll_config` - The PLL configuration parameters to achieve desired frequency |
| 533 | /// * `voltage_scale` - Optional voltage scaling for overclocking (required for >133MHz) | 438 | /// * `core_voltage` - Voltage scaling for overclocking (required for >133MHz) |
| 534 | /// | 439 | /// |
| 535 | /// # Returns | 440 | /// # Returns |
| 536 | /// | 441 | /// |
| @@ -549,11 +454,11 @@ impl ClockConfig { | |||
| 549 | /// post_div1: 3, // First post divider (1200 MHz / 3 = 400 MHz) | 454 | /// post_div1: 3, // First post divider (1200 MHz / 3 = 400 MHz) |
| 550 | /// post_div2: 2, // Second post divider (400 MHz / 2 = 200 MHz) | 455 | /// post_div2: 2, // Second post divider (400 MHz / 2 = 200 MHz) |
| 551 | /// }, | 456 | /// }, |
| 552 | /// Some(VoltageScale::V1_15) | 457 | /// CoreVoltage::V1_15 |
| 553 | /// ); | 458 | /// ); |
| 554 | /// ``` | 459 | /// ``` |
| 555 | #[cfg(feature = "rp2040")] | 460 | #[cfg(feature = "rp2040")] |
| 556 | pub fn manual_pll(xosc_hz: u32, pll_config: PllConfig, voltage_scale: Option<VoltageScale>) -> Self { | 461 | pub fn manual_pll(xosc_hz: u32, pll_config: PllConfig, core_voltage: CoreVoltage) -> Self { |
| 557 | // Calculate the actual output frequency for documentation | 462 | // Calculate the actual output frequency for documentation |
| 558 | // let ref_freq = xosc_hz / pll_config.refdiv as u32; | 463 | // let ref_freq = xosc_hz / pll_config.refdiv as u32; |
| 559 | // let vco_freq = ref_freq * pll_config.fbdiv as u32; | 464 | // let vco_freq = ref_freq * pll_config.fbdiv as u32; |
| @@ -587,7 +492,7 @@ impl ClockConfig { | |||
| 587 | div_frac: 0, | 492 | div_frac: 0, |
| 588 | }; | 493 | }; |
| 589 | 494 | ||
| 590 | config.voltage_scale = voltage_scale; | 495 | config.core_voltage = core_voltage; |
| 591 | config.peri_clk_src = Some(PeriClkSrc::Sys); | 496 | config.peri_clk_src = Some(PeriClkSrc::Sys); |
| 592 | 497 | ||
| 593 | // Set reasonable defaults for other clocks | 498 | // Set reasonable defaults for other clocks |
| @@ -865,7 +770,7 @@ pub struct RtcClkConfig { | |||
| 865 | /// | 770 | /// |
| 866 | /// # Parameters | 771 | /// # Parameters |
| 867 | /// | 772 | /// |
| 868 | /// * `input_hz`: The input frequency in Hz (typically the crystal frequency, e.g. 12MHz) | 773 | /// * `input_hz`: The input frequency in Hz (typically the crystal frequency, e.g. 12MHz for th most common one used on rp2040 boards) |
| 869 | /// * `target_hz`: The desired output frequency in Hz (e.g. 125MHz for standard RP2040 operation) | 774 | /// * `target_hz`: The desired output frequency in Hz (e.g. 125MHz for standard RP2040 operation) |
| 870 | /// | 775 | /// |
| 871 | /// # Returns | 776 | /// # Returns |
| @@ -990,7 +895,8 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 990 | 895 | ||
| 991 | // Set Core Voltage (RP2040 only), if we have config for it and we're not using the default | 896 | // Set Core Voltage (RP2040 only), if we have config for it and we're not using the default |
| 992 | #[cfg(feature = "rp2040")] | 897 | #[cfg(feature = "rp2040")] |
| 993 | if let Some(voltage) = config.voltage_scale { | 898 | { |
| 899 | let voltage = config.core_voltage; | ||
| 994 | let vreg = pac::VREG_AND_CHIP_RESET; | 900 | let vreg = pac::VREG_AND_CHIP_RESET; |
| 995 | let current_vsel = vreg.vreg().read().vsel(); | 901 | let current_vsel = vreg.vreg().read().vsel(); |
| 996 | let target_vsel = voltage as u8; | 902 | let target_vsel = voltage as u8; |
| @@ -1002,9 +908,9 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 1002 | // Wait for the voltage to stabilize. Use the provided delay or default based on voltage | 908 | // Wait for the voltage to stabilize. Use the provided delay or default based on voltage |
| 1003 | let settling_time_us = config.voltage_stabilization_delay_us.unwrap_or_else(|| { | 909 | let settling_time_us = config.voltage_stabilization_delay_us.unwrap_or_else(|| { |
| 1004 | match voltage { | 910 | match voltage { |
| 1005 | VoltageScale::V1_15 => 1000, // 1ms for 1.15V | 911 | CoreVoltage::V1_15 => 1000, // 1ms for 1.15V |
| 1006 | VoltageScale::V1_20 | VoltageScale::V1_25 | VoltageScale::V1_30 => 2000, // 2ms for higher voltages | 912 | CoreVoltage::V1_20 | CoreVoltage::V1_25 | CoreVoltage::V1_30 => 2000, // 2ms for higher voltages |
| 1007 | _ => 0, // no delay for all others | 913 | _ => 0, // no delay for all others |
| 1008 | } | 914 | } |
| 1009 | }); | 915 | }); |
| 1010 | 916 | ||
| @@ -1042,9 +948,8 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 1042 | }; | 948 | }; |
| 1043 | CLOCKS.xosc.store(xosc_freq, Ordering::Relaxed); | 949 | CLOCKS.xosc.store(xosc_freq, Ordering::Relaxed); |
| 1044 | 950 | ||
| 1045 | // SETUP TEMPORARY STABLE CLOCKS FIRST | 951 | // Setup temporary stable clocks first |
| 1046 | // Configure USB PLL for our stable temporary clock | 952 | // Configure USB PLL for our stable temporary clock |
| 1047 | // This follows the SDK's approach of using USB PLL as a stable intermediate clock | ||
| 1048 | let pll_usb_freq = match &config.xosc { | 953 | let pll_usb_freq = match &config.xosc { |
| 1049 | Some(config) => match &config.usb_pll { | 954 | Some(config) => match &config.usb_pll { |
| 1050 | Some(pll_usb_config) => { | 955 | Some(pll_usb_config) => { |
| @@ -1055,7 +960,13 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 1055 | reset::unreset_wait(peris); | 960 | reset::unreset_wait(peris); |
| 1056 | 961 | ||
| 1057 | // Configure the USB PLL - this should give us 48MHz | 962 | // Configure the USB PLL - this should give us 48MHz |
| 1058 | let usb_pll_freq = configure_pll(pac::PLL_USB, xosc_freq, *pll_usb_config); | 963 | let usb_pll_freq = match configure_pll(pac::PLL_USB, xosc_freq, *pll_usb_config) { |
| 964 | Ok(freq) => freq, | ||
| 965 | Err(_) => { | ||
| 966 | panic!("Failed to configure USB PLL"); | ||
| 967 | } | ||
| 968 | }; | ||
| 969 | |||
| 1059 | CLOCKS.pll_usb.store(usb_pll_freq, Ordering::Relaxed); | 970 | CLOCKS.pll_usb.store(usb_pll_freq, Ordering::Relaxed); |
| 1060 | usb_pll_freq | 971 | usb_pll_freq |
| 1061 | } | 972 | } |
| @@ -1074,7 +985,7 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 1074 | while c.clk_ref_selected().read() != pac::clocks::regs::ClkRefSelected(1 << ClkRefCtrlSrc::XOSC_CLKSRC as u32) {} | 985 | while c.clk_ref_selected().read() != pac::clocks::regs::ClkRefSelected(1 << ClkRefCtrlSrc::XOSC_CLKSRC as u32) {} |
| 1075 | 986 | ||
| 1076 | // First switch the system clock to a stable source (USB PLL at 48MHz) | 987 | // First switch the system clock to a stable source (USB PLL at 48MHz) |
| 1077 | // This follows the Pico SDK's approach to ensure stability during reconfiguration | 988 | // This follows the official Pico SDK's approach to ensure stability during reconfiguration |
| 1078 | c.clk_sys_ctrl().write(|w| { | 989 | c.clk_sys_ctrl().write(|w| { |
| 1079 | w.set_auxsrc(ClkSysCtrlAuxsrc::CLKSRC_PLL_USB); | 990 | w.set_auxsrc(ClkSysCtrlAuxsrc::CLKSRC_PLL_USB); |
| 1080 | w.set_src(ClkSysCtrlSrc::CLKSRC_CLK_SYS_AUX); | 991 | w.set_src(ClkSysCtrlSrc::CLKSRC_CLK_SYS_AUX); |
| @@ -1101,7 +1012,12 @@ pub(crate) unsafe fn init(config: ClockConfig) { | |||
| 1101 | reset::unreset_wait(peris); | 1012 | reset::unreset_wait(peris); |
| 1102 | 1013 | ||
| 1103 | // Configure the SYS PLL | 1014 | // Configure the SYS PLL |
| 1104 | let pll_sys_freq = configure_pll(pac::PLL_SYS, xosc_freq, *sys_pll_config); | 1015 | let pll_sys_freq = match configure_pll(pac::PLL_SYS, xosc_freq, *sys_pll_config) { |
| 1016 | Ok(freq) => freq, | ||
| 1017 | Err(_) => { | ||
| 1018 | panic!("Failed to configure system PLL"); | ||
| 1019 | } | ||
| 1020 | }; | ||
| 1105 | 1021 | ||
| 1106 | // Ensure PLL is locked and stable | 1022 | // Ensure PLL is locked and stable |
| 1107 | cortex_m::asm::delay(100); | 1023 | cortex_m::asm::delay(100); |
| @@ -1411,7 +1327,7 @@ fn start_xosc(crystal_hz: u32, delay_multiplier: u32) { | |||
| 1411 | 1327 | ||
| 1412 | /// PLL (Phase-Locked Loop) configuration | 1328 | /// PLL (Phase-Locked Loop) configuration |
| 1413 | #[inline(always)] | 1329 | #[inline(always)] |
| 1414 | fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> u32 { | 1330 | fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> Result<u32, &'static str> { |
| 1415 | // Calculate reference frequency | 1331 | // Calculate reference frequency |
| 1416 | let ref_freq = input_freq / config.refdiv as u32; | 1332 | let ref_freq = input_freq / config.refdiv as u32; |
| 1417 | 1333 | ||
| @@ -1482,7 +1398,7 @@ fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> u32 { | |||
| 1482 | timeout -= 1; | 1398 | timeout -= 1; |
| 1483 | if timeout == 0 { | 1399 | if timeout == 0 { |
| 1484 | // PLL failed to lock, return 0 to indicate failure | 1400 | // PLL failed to lock, return 0 to indicate failure |
| 1485 | return 0; | 1401 | return Err("PLL failed to lock"); |
| 1486 | } | 1402 | } |
| 1487 | } | 1403 | } |
| 1488 | 1404 | ||
| @@ -1502,7 +1418,7 @@ fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) -> u32 { | |||
| 1502 | cortex_m::asm::delay(100); | 1418 | cortex_m::asm::delay(100); |
| 1503 | 1419 | ||
| 1504 | // Calculate and return actual output frequency | 1420 | // Calculate and return actual output frequency |
| 1505 | vco_freq / ((config.post_div1 * config.post_div2) as u32) | 1421 | Ok(vco_freq / ((config.post_div1 * config.post_div2) as u32)) |
| 1506 | } | 1422 | } |
| 1507 | 1423 | ||
| 1508 | /// General purpose input clock pin. | 1424 | /// General purpose input clock pin. |
| @@ -1885,25 +1801,6 @@ mod tests { | |||
| 1885 | 1801 | ||
| 1886 | #[cfg(feature = "rp2040")] | 1802 | #[cfg(feature = "rp2040")] |
| 1887 | #[test] | 1803 | #[test] |
| 1888 | fn test_voltage_scale_bod_values() { | ||
| 1889 | // Test that each voltage level maps to the correct BOD threshold (approx. 90% of VDD) | ||
| 1890 | // This verifies our BOD settings match our documentation | ||
| 1891 | { | ||
| 1892 | assert_eq!(VoltageScale::V0_85.recommended_bod(), 0b0111); // ~0.774V (91% of 0.85V) | ||
| 1893 | assert_eq!(VoltageScale::V0_90.recommended_bod(), 0b1000); // ~0.817V (91% of 0.90V) | ||
| 1894 | assert_eq!(VoltageScale::V0_95.recommended_bod(), 0b1001); // ~0.860V (91% of 0.95V) | ||
| 1895 | assert_eq!(VoltageScale::V1_00.recommended_bod(), 0b1010); // ~0.903V (90% of 1.00V) | ||
| 1896 | assert_eq!(VoltageScale::V1_05.recommended_bod(), 0b1011); // ~0.946V (90% of 1.05V) | ||
| 1897 | assert_eq!(VoltageScale::V1_10.recommended_bod(), 0b1100); // ~0.989V (90% of 1.10V) | ||
| 1898 | assert_eq!(VoltageScale::V1_15.recommended_bod(), 0b1101); // ~1.032V (90% of 1.15V) | ||
| 1899 | assert_eq!(VoltageScale::V1_20.recommended_bod(), 0b1110); // ~1.075V (90% of 1.20V) | ||
| 1900 | assert_eq!(VoltageScale::V1_25.recommended_bod(), 0b1111); // ~1.118V (89% of 1.25V) | ||
| 1901 | assert_eq!(VoltageScale::V1_30.recommended_bod(), 0b1111); // ~1.118V (86% of 1.30V) - using max available | ||
| 1902 | } | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | #[cfg(feature = "rp2040")] | ||
| 1906 | #[test] | ||
| 1907 | fn test_find_pll_params() { | 1804 | fn test_find_pll_params() { |
| 1908 | #[cfg(feature = "rp2040")] | 1805 | #[cfg(feature = "rp2040")] |
| 1909 | { | 1806 | { |
| @@ -1942,7 +1839,12 @@ mod tests { | |||
| 1942 | let vco_freq = (16_000_000 / params.refdiv as u32) as u64 * params.fbdiv as u64; | 1839 | let vco_freq = (16_000_000 / params.refdiv as u32) as u64 * params.fbdiv as u64; |
| 1943 | let output_freq = (vco_freq / ((params.post_div1 * params.post_div2) as u64)) as u32; | 1840 | let output_freq = (vco_freq / ((params.post_div1 * params.post_div2) as u64)) as u32; |
| 1944 | 1841 | ||
| 1945 | // With a 16 MHz crystal, we might not get exactly 125 MHz | 1842 | // Test non-standard crystal with 15 MHz |
| 1843 | let params = find_pll_params(15_000_000, 125_000_000).unwrap(); | ||
| 1844 | let vco_freq = (15_000_000 / params.refdiv as u32) as u64 * params.fbdiv as u64; | ||
| 1845 | let output_freq = (vco_freq / ((params.post_div1 * params.post_div2) as u64)) as u32; | ||
| 1846 | |||
| 1847 | // With a 15 MHz crystal, we might not get exactly 125 MHz | ||
| 1946 | // Check that it's close enough (within 0.2% margin) | 1848 | // Check that it's close enough (within 0.2% margin) |
| 1947 | let freq_diff = if output_freq > 125_000_000 { | 1849 | let freq_diff = if output_freq > 125_000_000 { |
| 1948 | output_freq - 125_000_000 | 1850 | output_freq - 125_000_000 |
| @@ -2033,11 +1935,11 @@ mod tests { | |||
| 2033 | post_div1: 3, | 1935 | post_div1: 3, |
| 2034 | post_div2: 2, | 1936 | post_div2: 2, |
| 2035 | }, | 1937 | }, |
| 2036 | Some(VoltageScale::V1_15), | 1938 | CoreVoltage::V1_15, |
| 2037 | ); | 1939 | ); |
| 2038 | 1940 | ||
| 2039 | // Check voltage scale was set correctly | 1941 | // Check voltage scale was set correctly |
| 2040 | assert_eq!(config.voltage_scale, Some(VoltageScale::V1_15)); | 1942 | assert_eq!(config.core_voltage, CoreVoltage::V1_15); |
| 2041 | 1943 | ||
| 2042 | // Check PLL config was set correctly | 1944 | // Check PLL config was set correctly |
| 2043 | assert_eq!(config.xosc.as_ref().unwrap().sys_pll.as_ref().unwrap().refdiv, 1); | 1945 | assert_eq!(config.xosc.as_ref().unwrap().sys_pll.as_ref().unwrap().refdiv, 1); |
| @@ -2065,19 +1967,23 @@ mod tests { | |||
| 2065 | fn test_auto_voltage_scaling() { | 1967 | fn test_auto_voltage_scaling() { |
| 2066 | { | 1968 | { |
| 2067 | // Test automatic voltage scaling based on frequency | 1969 | // Test automatic voltage scaling based on frequency |
| 2068 | // Under 133 MHz should use default voltage (None) | 1970 | // Under 133 MHz should use default voltage (V1_10) |
| 2069 | let config = ClockConfig::at_sys_frequency_mhz(125); | 1971 | let config = ClockConfig::crystal_freq(125_000_000); |
| 2070 | assert_eq!(config.voltage_scale, None); | 1972 | assert_eq!(config.core_voltage, CoreVoltage::V1_10); |
| 2071 | 1973 | ||
| 2072 | // 133-200 MHz should use V1_15 | 1974 | // 133-200 MHz should use V1_15 |
| 2073 | let config = ClockConfig::at_sys_frequency_mhz(150); | 1975 | let config = ClockConfig::crystal_freq(150_000_000); |
| 2074 | assert_eq!(config.voltage_scale, Some(VoltageScale::V1_15)); | 1976 | assert_eq!(config.core_voltage, CoreVoltage::V1_15); |
| 2075 | let config = ClockConfig::at_sys_frequency_mhz(200); | 1977 | let config = ClockConfig::crystal_freq(200_000_000); |
| 2076 | assert_eq!(config.voltage_scale, Some(VoltageScale::V1_15)); | 1978 | assert_eq!(config.core_voltage, CoreVoltage::V1_15); |
| 2077 | 1979 | ||
| 2078 | // Above 200 MHz should use V1_20 | 1980 | // Above 200 MHz should use V1_25 |
| 2079 | let config = ClockConfig::at_sys_frequency_mhz(250); | 1981 | let config = ClockConfig::crystal_freq(250_000_000); |
| 2080 | assert_eq!(config.voltage_scale, Some(VoltageScale::V1_20)); | 1982 | assert_eq!(config.core_voltage, CoreVoltage::V1_15); |
| 1983 | |||
| 1984 | // Below 125 MHz should use V1_10 | ||
| 1985 | let config = ClockConfig::crystal_freq(100_000_000); | ||
| 1986 | assert_eq!(config.core_voltage, CoreVoltage::V1_10); | ||
| 2081 | } | 1987 | } |
| 2082 | } | 1988 | } |
| 2083 | } | 1989 | } |
diff --git a/examples/rp/src/bin/overclock.rs b/examples/rp/src/bin/overclock.rs index e3ac77340..f9a8c94d0 100644 --- a/examples/rp/src/bin/overclock.rs +++ b/examples/rp/src/bin/overclock.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | //! # Overclocking the RP2040 to 200 MHz | 1 | //! # Overclocking the RP2040 to 200 MHz |
| 2 | //! | 2 | //! |
| 3 | //! This example demonstrates how to configure the RP2040 to run at 200 MHz using a higher level API. | 3 | //! This example demonstrates how to configure the RP2040 to run at 200 MHz. |
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| @@ -17,19 +17,18 @@ const COUNT_TO: i64 = 10_000_000; | |||
| 17 | 17 | ||
| 18 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 19 | async fn main(_spawner: Spawner) -> ! { | 19 | async fn main(_spawner: Spawner) -> ! { |
| 20 | // Set up for clock frequency of 200 MHz | 20 | // Set up for clock frequency of 200 MHz, setting all necessary defaults. |
| 21 | // This will set all the necessary defaults including slightly raised voltage | 21 | let config = Config::new(ClockConfig::crystal_freq(200_000_000)); |
| 22 | let config = Config::new(ClockConfig::at_sys_frequency_mhz(200)); | ||
| 23 | 22 | ||
| 24 | // Show the voltage scale for verification | 23 | // Show the voltage scale for verification |
| 25 | info!("System core voltage: {}", Debug2Format(&config.clocks.voltage_scale)); | 24 | info!("System core voltage: {}", Debug2Format(&config.clocks.core_voltage)); |
| 26 | 25 | ||
| 27 | // Initialize the peripherals | 26 | // Initialize the peripherals |
| 28 | let p = embassy_rp::init(config); | 27 | let p = embassy_rp::init(config); |
| 29 | 28 | ||
| 30 | // Show CPU frequency for verification | 29 | // Show CPU frequency for verification |
| 31 | let sys_freq = clk_sys_freq(); | 30 | let sys_freq = clk_sys_freq(); |
| 32 | info!("System clock frequency: {} Hz", sys_freq); | 31 | info!("System clock frequency: {} MHz", sys_freq / 1_000_000); |
| 33 | 32 | ||
| 34 | // LED to indicate the system is running | 33 | // LED to indicate the system is running |
| 35 | let mut led = Output::new(p.PIN_25, Level::Low); | 34 | let mut led = Output::new(p.PIN_25, Level::Low); |
diff --git a/examples/rp/src/bin/overclock_manual.rs b/examples/rp/src/bin/overclock_manual.rs index ad6abf0e7..35160b250 100644 --- a/examples/rp/src/bin/overclock_manual.rs +++ b/examples/rp/src/bin/overclock_manual.rs | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | use defmt::*; | 8 | use defmt::*; |
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_rp::clocks; | 10 | use embassy_rp::clocks; |
| 11 | use embassy_rp::clocks::{ClockConfig, PllConfig, VoltageScale}; | 11 | use embassy_rp::clocks::{ClockConfig, CoreVoltage, PllConfig}; |
| 12 | use embassy_rp::config::Config; | 12 | use embassy_rp::config::Config; |
| 13 | use embassy_rp::gpio::{Level, Output}; | 13 | use embassy_rp::gpio::{Level, Output}; |
| 14 | use embassy_time::{Duration, Instant, Timer}; | 14 | use embassy_time::{Duration, Instant, Timer}; |
| @@ -16,23 +16,21 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 16 | 16 | ||
| 17 | const COUNT_TO: i64 = 10_000_000; | 17 | const COUNT_TO: i64 = 10_000_000; |
| 18 | 18 | ||
| 19 | /// Configure the RP2040 for 200 MHz operation by manually specifying | 19 | /// Configure the RP2040 for 200 MHz operation by manually specifying the PLL settings. |
| 20 | /// all the required parameters instead of using higher-level APIs. | ||
| 21 | fn configure_manual_overclock() -> Config { | 20 | fn configure_manual_overclock() -> Config { |
| 22 | // Set the PLL configuration manually, starting from default values | 21 | // Set the PLL configuration manually, starting from default values |
| 23 | let mut config = Config::default(); | 22 | let mut config = Config::default(); |
| 24 | 23 | ||
| 25 | // Set the system clock to 200 MHz using a PLL with a reference frequency of 12 MHz | 24 | // Set the system clock to 200 MHz |
| 26 | config.clocks = ClockConfig::manual_pll( | 25 | config.clocks = ClockConfig::manual_pll( |
| 27 | 12_000_000, | 26 | 12_000_000, // Crystal frequency, 12 MHz is common. If using custom, set to your value. |
| 28 | PllConfig { | 27 | PllConfig { |
| 29 | refdiv: 1, | 28 | refdiv: 1, // Reference divider |
| 30 | fbdiv: 100, | 29 | fbdiv: 100, // Feedback divider |
| 31 | post_div1: 3, | 30 | post_div1: 3, // Post divider 1 |
| 32 | post_div2: 2, | 31 | post_div2: 2, // Post divider 2 |
| 33 | }, | 32 | }, |
| 34 | // For 200 MHz, we need a voltage scale of 1.15V | 33 | CoreVoltage::V1_15, // Core voltage, should be set to V1_15 for 200 MHz |
| 35 | Some(VoltageScale::V1_15), | ||
| 36 | ); | 34 | ); |
| 37 | 35 | ||
| 38 | config | 36 | config |
diff --git a/tests/rp/src/bin/overclock.rs b/tests/rp/src/bin/overclock.rs index e4845a55f..6c58a6b90 100644 --- a/tests/rp/src/bin/overclock.rs +++ b/tests/rp/src/bin/overclock.rs | |||
| @@ -14,7 +14,7 @@ use embassy_rp::clocks; | |||
| 14 | #[cfg(feature = "rp2040")] | 14 | #[cfg(feature = "rp2040")] |
| 15 | use embassy_rp::clocks::ClockConfig; | 15 | use embassy_rp::clocks::ClockConfig; |
| 16 | #[cfg(feature = "rp2040")] | 16 | #[cfg(feature = "rp2040")] |
| 17 | use embassy_rp::clocks::VoltageScale; | 17 | use embassy_rp::clocks::CoreVoltage; |
| 18 | use embassy_rp::config::Config; | 18 | use embassy_rp::config::Config; |
| 19 | use embassy_time::Instant; | 19 | use embassy_time::Instant; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -31,15 +31,15 @@ async fn main(_spawner: Spawner) { | |||
| 31 | // Initialize with 200MHz clock configuration for RP2040, other chips will use default clock | 31 | // Initialize with 200MHz clock configuration for RP2040, other chips will use default clock |
| 32 | #[cfg(feature = "rp2040")] | 32 | #[cfg(feature = "rp2040")] |
| 33 | { | 33 | { |
| 34 | config.clocks = ClockConfig::at_sys_frequency_mhz(200); | 34 | config.clocks = ClockConfig::crystal_freq(200_000_000); |
| 35 | let voltage = config.clocks.voltage_scale.unwrap(); | 35 | let voltage = config.clocks.core_voltage; |
| 36 | assert!(matches!(voltage, VoltageScale::V1_15), "Expected voltage scale V1_15"); | 36 | assert!(matches!(voltage, CoreVoltage::V1_15), "Expected voltage scale V1_15"); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | let _p = embassy_rp::init(config); | 39 | let _p = embassy_rp::init(config); |
| 40 | 40 | ||
| 41 | // Test the system speed | ||
| 41 | let (time_elapsed, clk_sys_freq) = { | 42 | let (time_elapsed, clk_sys_freq) = { |
| 42 | // Test the system speed | ||
| 43 | let mut counter = 0; | 43 | let mut counter = 0; |
| 44 | let start = Instant::now(); | 44 | let start = Instant::now(); |
| 45 | while counter < COUNT_TO { | 45 | while counter < COUNT_TO { |
