@@ -406,16 +406,19 @@ pub mod config {
406406 /// Settings for the internal capacitors.
407407 #[ cfg( feature = "nrf5340-app-s" ) ]
408408 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.
410410 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.
412413 pub lfxo : Option < LfxoCapacitance > ,
413414 }
414415
415416 /// Internal capacitance value for the HFXO.
416417 #[ cfg( feature = "nrf5340-app-s" ) ]
417418 #[ derive( Copy , Clone ) ]
418419 pub enum HfxoCapacitance {
420+ /// Use external capacitors
421+ External ,
419422 /// 7.0 pF
420423 _7_0pF,
421424 /// 7.5 pF
@@ -475,8 +478,9 @@ pub mod config {
475478 #[ cfg( feature = "nrf5340-app-s" ) ]
476479 impl HfxoCapacitance {
477480 /// The capacitance value times two.
478- pub ( crate ) const fn value2 ( self ) -> i32 {
481+ pub ( crate ) fn value2 ( self ) -> i32 {
479482 match self {
483+ HfxoCapacitance :: External => unreachable ! ( ) ,
480484 HfxoCapacitance :: _7_0pF => 14 ,
481485 HfxoCapacitance :: _7_5pF => 15 ,
482486 HfxoCapacitance :: _8_0pF => 16 ,
@@ -506,11 +510,17 @@ pub mod config {
506510 HfxoCapacitance :: _20_0pF => 40 ,
507511 }
508512 }
513+
514+ pub ( crate ) fn external ( self ) -> bool {
515+ matches ! ( self , Self :: External )
516+ }
509517 }
510518
511519 /// Internal capacitance value for the LFXO.
512520 #[ cfg( feature = "nrf5340-app-s" ) ]
513521 pub enum LfxoCapacitance {
522+ /// Use external capacitors
523+ External = 0 ,
514524 /// 6 pF
515525 _6pF = 1 ,
516526 /// 7 pF
@@ -523,6 +533,7 @@ pub mod config {
523533 impl From < LfxoCapacitance > for super :: pac:: oscillators:: vals:: Intcap {
524534 fn from ( t : LfxoCapacitance ) -> Self {
525535 match t {
536+ LfxoCapacitance :: External => Self :: EXTERNAL ,
526537 LfxoCapacitance :: _6pF => Self :: C6PF ,
527538 LfxoCapacitance :: _7pF => Self :: C7PF ,
528539 LfxoCapacitance :: _9pF => Self :: C9PF ,
@@ -720,6 +731,29 @@ pub fn init(config: config::Config) -> Peripherals {
720731 }
721732 }
722733
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+
723757 // GLITCHDET is only accessible for secure code
724758 #[ cfg( all( feature = "_nrf54l" , feature = "_s" ) ) ]
725759 {
@@ -953,17 +987,21 @@ pub fn init(config: config::Config) -> Peripherals {
953987 #[ cfg( feature = "nrf5340-app-s" ) ]
954988 {
955989 if let Some ( cap) = config. internal_capacitors . hfxo {
956- let mut slope = pac:: FICR . xosc32mtrim ( ) . read ( ) . slope ( ) as i32 ;
957- let offset = pac:: FICR . xosc32mtrim ( ) . read ( ) . offset ( ) as i32 ;
958- // slope is a signed 5-bit integer
959- if slope >= 16 {
960- slope -= 32 ;
990+ if cap. external ( ) {
991+ pac:: OSCILLATORS . xosc32mcaps ( ) . write ( |w| w. set_enable ( false ) ) ;
992+ } else {
993+ let mut slope = pac:: FICR . xosc32mtrim ( ) . read ( ) . slope ( ) as i32 ;
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+ } ) ;
9611004 }
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- } ) ;
9671005 }
9681006 if let Some ( cap) = config. internal_capacitors . lfxo {
9691007 pac:: OSCILLATORS . xosc32ki ( ) . intcap ( ) . write ( |w| w. set_intcap ( cap. into ( ) ) ) ;
0 commit comments