diff options
| author | Matthew Tran <[email protected]> | 2025-03-01 23:01:06 -0600 |
|---|---|---|
| committer | Matthew Tran <[email protected]> | 2025-03-02 00:06:41 -0600 |
| commit | ec30e3ef91f0dfa9983990c710ad3a4574847634 (patch) | |
| tree | 9cf918d31cfcf70ab0027bcb197e462caf98fcc2 | |
| parent | 17301c00e986c5b8536435ea31ebf5aaf13aed17 (diff) | |
nrf5340: add internal capacitor config
| -rw-r--r-- | embassy-nrf/src/lib.rs | 156 |
1 files changed, 155 insertions, 1 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 23888b390..f2cf0d77e 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -360,6 +360,133 @@ pub mod config { | |||
| 360 | pub regmain: bool, | 360 | pub regmain: bool, |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | /// Settings for the internal capacitors. | ||
| 364 | #[cfg(feature = "nrf5340-app-s")] | ||
| 365 | pub struct InternalCapacitors { | ||
| 366 | /// Config for the internal capacitors on pins XC1 and XC2. | ||
| 367 | pub hfxo: Option<HfxoCapacitance>, | ||
| 368 | /// Config for the internal capacitors between pins XL1 and XL2. | ||
| 369 | pub lfxo: Option<LfxoCapacitance>, | ||
| 370 | } | ||
| 371 | |||
| 372 | /// Internal capacitance value for the HFXO. | ||
| 373 | #[cfg(feature = "nrf5340-app-s")] | ||
| 374 | #[derive(Copy, Clone)] | ||
| 375 | pub enum HfxoCapacitance { | ||
| 376 | /// 7.0 pF | ||
| 377 | _7_0pF, | ||
| 378 | /// 7.5 pF | ||
| 379 | _7_5pF, | ||
| 380 | /// 8.0 pF | ||
| 381 | _8_0pF, | ||
| 382 | /// 8.5 pF | ||
| 383 | _8_5pF, | ||
| 384 | /// 9.0 pF | ||
| 385 | _9_0pF, | ||
| 386 | /// 9.5 pF | ||
| 387 | _9_5pF, | ||
| 388 | /// 10.0 pF | ||
| 389 | _10_0pF, | ||
| 390 | /// 10.5 pF | ||
| 391 | _10_5pF, | ||
| 392 | /// 11.0 pF | ||
| 393 | _11_0pF, | ||
| 394 | /// 11.5 pF | ||
| 395 | _11_5pF, | ||
| 396 | /// 12.0 pF | ||
| 397 | _12_0pF, | ||
| 398 | /// 12.5 pF | ||
| 399 | _12_5pF, | ||
| 400 | /// 13.0 pF | ||
| 401 | _13_0pF, | ||
| 402 | /// 13.5 pF | ||
| 403 | _13_5pF, | ||
| 404 | /// 14.0 pF | ||
| 405 | _14_0pF, | ||
| 406 | /// 14.5 pF | ||
| 407 | _14_5pF, | ||
| 408 | /// 15.0 pF | ||
| 409 | _15_0pF, | ||
| 410 | /// 15.5 pF | ||
| 411 | _15_5pF, | ||
| 412 | /// 16.0 pF | ||
| 413 | _16_0pF, | ||
| 414 | /// 16.5 pF | ||
| 415 | _16_5pF, | ||
| 416 | /// 17.0 pF | ||
| 417 | _17_0pF, | ||
| 418 | /// 17.5 pF | ||
| 419 | _17_5pF, | ||
| 420 | /// 18.0 pF | ||
| 421 | _18_0pF, | ||
| 422 | /// 18.5 pF | ||
| 423 | _18_5pF, | ||
| 424 | /// 19.0 pF | ||
| 425 | _19_0pF, | ||
| 426 | /// 19.5 pF | ||
| 427 | _19_5pF, | ||
| 428 | /// 20.0 pF | ||
| 429 | _20_0pF, | ||
| 430 | } | ||
| 431 | |||
| 432 | #[cfg(feature = "nrf5340-app-s")] | ||
| 433 | impl HfxoCapacitance { | ||
| 434 | /// The capacitance value times two. | ||
| 435 | pub(crate) const fn value2(self) -> i32 { | ||
| 436 | match self { | ||
| 437 | HfxoCapacitance::_7_0pF => 14, | ||
| 438 | HfxoCapacitance::_7_5pF => 15, | ||
| 439 | HfxoCapacitance::_8_0pF => 16, | ||
| 440 | HfxoCapacitance::_8_5pF => 17, | ||
| 441 | HfxoCapacitance::_9_0pF => 18, | ||
| 442 | HfxoCapacitance::_9_5pF => 19, | ||
| 443 | HfxoCapacitance::_10_0pF => 20, | ||
| 444 | HfxoCapacitance::_10_5pF => 21, | ||
| 445 | HfxoCapacitance::_11_0pF => 22, | ||
| 446 | HfxoCapacitance::_11_5pF => 23, | ||
| 447 | HfxoCapacitance::_12_0pF => 24, | ||
| 448 | HfxoCapacitance::_12_5pF => 25, | ||
| 449 | HfxoCapacitance::_13_0pF => 26, | ||
| 450 | HfxoCapacitance::_13_5pF => 27, | ||
| 451 | HfxoCapacitance::_14_0pF => 28, | ||
| 452 | HfxoCapacitance::_14_5pF => 29, | ||
| 453 | HfxoCapacitance::_15_0pF => 30, | ||
| 454 | HfxoCapacitance::_15_5pF => 31, | ||
| 455 | HfxoCapacitance::_16_0pF => 32, | ||
| 456 | HfxoCapacitance::_16_5pF => 33, | ||
| 457 | HfxoCapacitance::_17_0pF => 34, | ||
| 458 | HfxoCapacitance::_17_5pF => 35, | ||
| 459 | HfxoCapacitance::_18_0pF => 36, | ||
| 460 | HfxoCapacitance::_18_5pF => 37, | ||
| 461 | HfxoCapacitance::_19_0pF => 38, | ||
| 462 | HfxoCapacitance::_19_5pF => 39, | ||
| 463 | HfxoCapacitance::_20_0pF => 40, | ||
| 464 | } | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | /// Internal capacitance value for the LFXO. | ||
| 469 | #[cfg(feature = "nrf5340-app-s")] | ||
| 470 | pub enum LfxoCapacitance { | ||
| 471 | /// 6 pF | ||
| 472 | _6pF = 1, | ||
| 473 | /// 7 pF | ||
| 474 | _7pF = 2, | ||
| 475 | /// 9 pF | ||
| 476 | _9pF = 3, | ||
| 477 | } | ||
| 478 | |||
| 479 | #[cfg(feature = "nrf5340-app-s")] | ||
| 480 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { | ||
| 481 | fn from(t: LfxoCapacitance) -> Self { | ||
| 482 | match t { | ||
| 483 | LfxoCapacitance::_6pF => Self::C6PF, | ||
| 484 | LfxoCapacitance::_7pF => Self::C7PF, | ||
| 485 | LfxoCapacitance::_9pF => Self::C9PF, | ||
| 486 | } | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 363 | /// Configuration for peripherals. Default configuration should work on any nRF chip. | 490 | /// Configuration for peripherals. Default configuration should work on any nRF chip. |
| 364 | #[non_exhaustive] | 491 | #[non_exhaustive] |
| 365 | pub struct Config { | 492 | pub struct Config { |
| @@ -367,6 +494,10 @@ pub mod config { | |||
| 367 | pub hfclk_source: HfclkSource, | 494 | pub hfclk_source: HfclkSource, |
| 368 | /// Low frequency clock source. | 495 | /// Low frequency clock source. |
| 369 | pub lfclk_source: LfclkSource, | 496 | pub lfclk_source: LfclkSource, |
| 497 | #[cfg(feature = "nrf5340-app-s")] | ||
| 498 | /// Internal capacitor configuration, for use with the `ExternalXtal` clock source. See | ||
| 499 | /// nrf5340-PS ยง4.12. | ||
| 500 | pub internal_capacitors: InternalCapacitors, | ||
| 370 | #[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))] | 501 | #[cfg(not(any(feature = "_nrf5340-net", feature = "_nrf54l")))] |
| 371 | /// DCDC configuration. | 502 | /// DCDC configuration. |
| 372 | pub dcdc: DcdcConfig, | 503 | pub dcdc: DcdcConfig, |
| @@ -388,6 +519,8 @@ pub mod config { | |||
| 388 | // xtals if they know they have them. | 519 | // xtals if they know they have them. |
| 389 | hfclk_source: HfclkSource::Internal, | 520 | hfclk_source: HfclkSource::Internal, |
| 390 | lfclk_source: LfclkSource::InternalRC, | 521 | lfclk_source: LfclkSource::InternalRC, |
| 522 | #[cfg(feature = "nrf5340-app-s")] | ||
| 523 | internal_capacitors: InternalCapacitors { hfxo: None, lfxo: None }, | ||
| 391 | #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))] | 524 | #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))] |
| 392 | dcdc: DcdcConfig { | 525 | dcdc: DcdcConfig { |
| 393 | #[cfg(feature = "nrf52840")] | 526 | #[cfg(feature = "nrf52840")] |
| @@ -687,6 +820,27 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 687 | cortex_m::peripheral::SCB::sys_reset(); | 820 | cortex_m::peripheral::SCB::sys_reset(); |
| 688 | } | 821 | } |
| 689 | 822 | ||
| 823 | // Configure internal capacitors | ||
| 824 | #[cfg(feature = "nrf5340-app-s")] | ||
| 825 | { | ||
| 826 | if let Some(cap) = config.internal_capacitors.hfxo { | ||
| 827 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; | ||
| 828 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; | ||
| 829 | // slope is a signed 5-bit integer | ||
| 830 | if slope >= 16 { | ||
| 831 | slope -= 32; | ||
| 832 | } | ||
| 833 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 834 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 835 | w.set_capvalue(capvalue as u8); | ||
| 836 | w.set_enable(true); | ||
| 837 | }); | ||
| 838 | } | ||
| 839 | if let Some(cap) = config.internal_capacitors.lfxo { | ||
| 840 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); | ||
| 841 | } | ||
| 842 | } | ||
| 843 | |||
| 690 | let r = pac::CLOCK; | 844 | let r = pac::CLOCK; |
| 691 | 845 | ||
| 692 | // Start HFCLK. | 846 | // Start HFCLK. |
| @@ -753,7 +907,7 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 753 | config::LfclkSource::ExternalLowSwing => lfxo = true, | 907 | config::LfclkSource::ExternalLowSwing => lfxo = true, |
| 754 | #[cfg(not(feature = "lfxo-pins-as-gpio"))] | 908 | #[cfg(not(feature = "lfxo-pins-as-gpio"))] |
| 755 | config::LfclkSource::ExternalFullSwing => { | 909 | config::LfclkSource::ExternalFullSwing => { |
| 756 | #[cfg(all(feature = "_nrf5340-app"))] | 910 | #[cfg(feature = "_nrf5340-app")] |
| 757 | pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true)); | 911 | pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true)); |
| 758 | lfxo = true; | 912 | lfxo = true; |
| 759 | } | 913 | } |
