diff options
Diffstat (limited to 'embassy-nrf/src/lib.rs')
| -rw-r--r-- | embassy-nrf/src/lib.rs | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 7c26a6184..716eec961 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -406,9 +406,10 @@ pub mod config { | |||
| 406 | /// Settings for the internal capacitors. | 406 | /// Settings for the internal capacitors. |
| 407 | #[cfg(feature = "nrf5340-app-s")] | 407 | #[cfg(feature = "nrf5340-app-s")] |
| 408 | pub struct InternalCapacitors { | 408 | pub struct InternalCapacitors { |
| 409 | /// Config for the internal capacitors on pins XC1 and XC2. | 409 | /// Config for the internal capacitors on pins XC1 and XC2. Pass `None` to not touch it. |
| 410 | pub hfxo: Option<HfxoCapacitance>, | 410 | pub hfxo: Option<HfxoCapacitance>, |
| 411 | /// Config for the internal capacitors between pins XL1 and XL2. | 411 | /// Config for the internal capacitors between pins XL1 and XL2. Pass `None` to not touch |
| 412 | /// it. | ||
| 412 | pub lfxo: Option<LfxoCapacitance>, | 413 | pub lfxo: Option<LfxoCapacitance>, |
| 413 | } | 414 | } |
| 414 | 415 | ||
| @@ -416,6 +417,8 @@ pub mod config { | |||
| 416 | #[cfg(feature = "nrf5340-app-s")] | 417 | #[cfg(feature = "nrf5340-app-s")] |
| 417 | #[derive(Copy, Clone)] | 418 | #[derive(Copy, Clone)] |
| 418 | pub enum HfxoCapacitance { | 419 | pub enum HfxoCapacitance { |
| 420 | /// Use external capacitors | ||
| 421 | External, | ||
| 419 | /// 7.0 pF | 422 | /// 7.0 pF |
| 420 | _7_0pF, | 423 | _7_0pF, |
| 421 | /// 7.5 pF | 424 | /// 7.5 pF |
| @@ -475,8 +478,9 @@ pub mod config { | |||
| 475 | #[cfg(feature = "nrf5340-app-s")] | 478 | #[cfg(feature = "nrf5340-app-s")] |
| 476 | impl HfxoCapacitance { | 479 | impl HfxoCapacitance { |
| 477 | /// The capacitance value times two. | 480 | /// The capacitance value times two. |
| 478 | pub(crate) const fn value2(self) -> i32 { | 481 | pub(crate) fn value2(self) -> i32 { |
| 479 | match self { | 482 | match self { |
| 483 | HfxoCapacitance::External => unreachable!(), | ||
| 480 | HfxoCapacitance::_7_0pF => 14, | 484 | HfxoCapacitance::_7_0pF => 14, |
| 481 | HfxoCapacitance::_7_5pF => 15, | 485 | HfxoCapacitance::_7_5pF => 15, |
| 482 | HfxoCapacitance::_8_0pF => 16, | 486 | HfxoCapacitance::_8_0pF => 16, |
| @@ -506,11 +510,17 @@ pub mod config { | |||
| 506 | HfxoCapacitance::_20_0pF => 40, | 510 | HfxoCapacitance::_20_0pF => 40, |
| 507 | } | 511 | } |
| 508 | } | 512 | } |
| 513 | |||
| 514 | pub(crate) fn external(self) -> bool { | ||
| 515 | matches!(self, Self::External) | ||
| 516 | } | ||
| 509 | } | 517 | } |
| 510 | 518 | ||
| 511 | /// Internal capacitance value for the LFXO. | 519 | /// Internal capacitance value for the LFXO. |
| 512 | #[cfg(feature = "nrf5340-app-s")] | 520 | #[cfg(feature = "nrf5340-app-s")] |
| 513 | pub enum LfxoCapacitance { | 521 | pub enum LfxoCapacitance { |
| 522 | /// Use external capacitors | ||
| 523 | External = 0, | ||
| 514 | /// 6 pF | 524 | /// 6 pF |
| 515 | _6pF = 1, | 525 | _6pF = 1, |
| 516 | /// 7 pF | 526 | /// 7 pF |
| @@ -523,6 +533,7 @@ pub mod config { | |||
| 523 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { | 533 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { |
| 524 | fn from(t: LfxoCapacitance) -> Self { | 534 | fn from(t: LfxoCapacitance) -> Self { |
| 525 | match t { | 535 | match t { |
| 536 | LfxoCapacitance::External => Self::EXTERNAL, | ||
| 526 | LfxoCapacitance::_6pF => Self::C6PF, | 537 | LfxoCapacitance::_6pF => Self::C6PF, |
| 527 | LfxoCapacitance::_7pF => Self::C7PF, | 538 | LfxoCapacitance::_7pF => Self::C7PF, |
| 528 | LfxoCapacitance::_9pF => Self::C9PF, | 539 | LfxoCapacitance::_9pF => Self::C9PF, |
| @@ -720,6 +731,29 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 720 | } | 731 | } |
| 721 | } | 732 | } |
| 722 | 733 | ||
| 734 | // Apply trimming values from the FICR. | ||
| 735 | #[cfg(any( | ||
| 736 | all(feature = "_nrf5340-app", feature = "_s"), | ||
| 737 | all(feature = "_nrf54l", feature = "_s"), | ||
| 738 | feature = "_nrf5340-net", | ||
| 739 | ))] | ||
| 740 | { | ||
| 741 | #[cfg(feature = "_nrf5340")] | ||
| 742 | let n = 32; | ||
| 743 | #[cfg(feature = "_nrf54l")] | ||
| 744 | let n = 64; | ||
| 745 | for i in 0..n { | ||
| 746 | let info = pac::FICR.trimcnf(i); | ||
| 747 | let addr = info.addr().read(); | ||
| 748 | if addr == 0 || addr == 0xFFFF_FFFF { | ||
| 749 | break; | ||
| 750 | } | ||
| 751 | unsafe { | ||
| 752 | (addr as *mut u32).write_volatile(info.data().read()); | ||
| 753 | } | ||
| 754 | } | ||
| 755 | } | ||
| 756 | |||
| 723 | // GLITCHDET is only accessible for secure code | 757 | // GLITCHDET is only accessible for secure code |
| 724 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | 758 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 725 | { | 759 | { |
| @@ -953,17 +987,21 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 953 | #[cfg(feature = "nrf5340-app-s")] | 987 | #[cfg(feature = "nrf5340-app-s")] |
| 954 | { | 988 | { |
| 955 | if let Some(cap) = config.internal_capacitors.hfxo { | 989 | if let Some(cap) = config.internal_capacitors.hfxo { |
| 956 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; | 990 | if cap.external() { |
| 957 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; | 991 | pac::OSCILLATORS.xosc32mcaps().write(|w| w.set_enable(false)); |
| 958 | // slope is a signed 5-bit integer | 992 | } else { |
| 959 | if slope >= 16 { | 993 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; |
| 960 | slope -= 32; | 994 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; |
| 995 | // slope is a signed 5-bit integer | ||
| 996 | if slope >= 16 { | ||
| 997 | slope -= 32; | ||
| 998 | } | ||
| 999 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 1000 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 1001 | w.set_capvalue(capvalue as u8); | ||
| 1002 | w.set_enable(true); | ||
| 1003 | }); | ||
| 961 | } | 1004 | } |
| 962 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 963 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 964 | w.set_capvalue(capvalue as u8); | ||
| 965 | w.set_enable(true); | ||
| 966 | }); | ||
| 967 | } | 1005 | } |
| 968 | if let Some(cap) = config.internal_capacitors.lfxo { | 1006 | if let Some(cap) = config.internal_capacitors.lfxo { |
| 969 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); | 1007 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); |
