Skip to content

Commit 1b4f788

Browse files
committed
nrf5340: configure LFCLK
1 parent 2e7a2b6 commit 1b4f788

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

embassy-nrf/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ nfc-pins-as-gpio = []
5757
## * nRF52820, nRF52833, nRF52840: P0_18
5858
reset-pin-as-gpio = []
5959

60+
## Allow using the LFXO pins as regular GPIO pins (P0_00/P0_01 on nRF53)
61+
lfxo-pins-as-gpio = []
62+
6063
## Implements the MultiwriteNorFlash trait for QSPI. Should only be enabled if your external
6164
## flash supports the semantics described [here](https://docs.rs/embedded-storage/0.3.1/embedded_storage/nor_flash/trait.MultiwriteNorFlash.html)
6265
qspi-multiwrite-flash = []

embassy-nrf/src/chips/nrf5340_app.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ embassy_hal_internal::peripherals! {
262262
PPI_GROUP5,
263263

264264
// GPIO port 0
265+
#[cfg(any(not(feature = "_nrf5340"), feature = "lfxo-pins-as-gpio"))]
265266
P0_00,
267+
#[cfg(any(not(feature = "_nrf5340"), feature = "lfxo-pins-as-gpio"))]
266268
P0_01,
267269
#[cfg(feature = "nfc-pins-as-gpio")]
268270
P0_02,
@@ -368,7 +370,9 @@ impl_pdm!(PDM0, PDM0, PDM0);
368370
impl_qdec!(QDEC0, QDEC0, QDEC0);
369371
impl_qdec!(QDEC1, QDEC1, QDEC1);
370372

373+
#[cfg(any(not(feature = "_nrf5340"), feature = "lfxo-pins-as-gpio"))]
371374
impl_pin!(P0_00, 0, 0);
375+
#[cfg(any(not(feature = "_nrf5340"), feature = "lfxo-pins-as-gpio"))]
372376
impl_pin!(P0_01, 0, 1);
373377
#[cfg(feature = "nfc-pins-as-gpio")]
374378
impl_pin!(P0_02, 0, 2);

embassy-nrf/src/lib.rs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ compile_error!("feature `reset-pin-as-gpio` is only valid for nRF52 series chips
6565
#[cfg(all(feature = "nfc-pins-as-gpio", not(any(feature = "_nrf52", feature = "_nrf5340-app"))))]
6666
compile_error!("feature `nfc-pins-as-gpio` is only valid for nRF52, or nRF53's application core.");
6767

68+
#[cfg(all(feature = "lfxo-pins-as-gpio", not(any(feature = "_nrf5340"))))]
69+
compile_error!("feature `lfxo-pins-as-gpio` is only valid for nRF53 series chips.");
70+
6871
// This mod MUST go first, so that the others see its macros.
6972
pub(crate) mod fmt;
7073
pub(crate) mod util;
@@ -282,15 +285,24 @@ pub mod config {
282285
/// Internal RC oscillator
283286
InternalRC,
284287
/// Synthesized from the high frequency clock source.
285-
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))]
288+
#[cfg(not(any(feature = "_nrf91")))]
286289
Synthesized,
287290
/// External source from xtal.
291+
#[cfg(not(all(feature = "_nrf5340", feature = "lfxo-pins-as-gpio")))]
288292
ExternalXtal,
289293
/// External source from xtal with low swing applied.
290-
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
294+
#[cfg(not(any(
295+
all(feature = "_nrf5340", feature = "lfxo-pins-as-gpio"),
296+
feature = "_nrf91",
297+
feature = "_nrf54l"
298+
)))]
291299
ExternalLowSwing,
292300
/// External source from xtal with full swing applied.
293-
#[cfg(not(any(feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
301+
#[cfg(not(any(
302+
all(feature = "_nrf5340", feature = "lfxo-pins-as-gpio"),
303+
feature = "_nrf91",
304+
feature = "_nrf54l"
305+
)))]
294306
ExternalFullSwing,
295307
}
296308

@@ -706,6 +718,19 @@ pub fn init(config: config::Config) -> Peripherals {
706718
}
707719
}
708720

721+
// Workaround for anomaly 140
722+
#[cfg(feature = "nrf5340-app-s")]
723+
if unsafe { (0x50032420 as *mut u32).read_volatile() } & 0x80000000 != 0 {
724+
r.events_lfclkstarted().write_value(0);
725+
r.lfclksrc()
726+
.write(|w| w.set_src(nrf_pac::clock::vals::Lfclksrc::LFSYNT));
727+
r.tasks_lfclkstart().write_value(1);
728+
while r.events_lfclkstarted().read() == 0 {}
729+
r.events_lfclkstarted().write_value(0);
730+
r.tasks_lfclkstop().write_value(1);
731+
r.lfclksrc().write(|w| w.set_src(nrf_pac::clock::vals::Lfclksrc::LFRC));
732+
}
733+
709734
// Configure LFCLK.
710735
#[cfg(not(any(feature = "_nrf51", feature = "_nrf5340", feature = "_nrf91", feature = "_nrf54l")))]
711736
match config.lfclk_source {
@@ -723,6 +748,36 @@ pub fn init(config: config::Config) -> Peripherals {
723748
w.set_bypass(true);
724749
}),
725750
}
751+
#[cfg(feature = "_nrf5340")]
752+
{
753+
#[allow(unused_mut)]
754+
let mut lfxo = false;
755+
match config.lfclk_source {
756+
config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),
757+
config::LfclkSource::Synthesized => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFSYNT)),
758+
#[cfg(not(feature = "lfxo-pins-as-gpio"))]
759+
config::LfclkSource::ExternalXtal => lfxo = true,
760+
#[cfg(not(feature = "lfxo-pins-as-gpio"))]
761+
config::LfclkSource::ExternalLowSwing => lfxo = true,
762+
#[cfg(not(feature = "lfxo-pins-as-gpio"))]
763+
config::LfclkSource::ExternalFullSwing => {
764+
#[cfg(all(feature = "_nrf5340-app"))]
765+
pac::OSCILLATORS.xosc32ki().bypass().write(|w| w.set_bypass(true));
766+
lfxo = true;
767+
}
768+
}
769+
if lfxo {
770+
if cfg!(feature = "_s") {
771+
// MCUSEL is only accessible from secure code.
772+
let p0 = pac::P0;
773+
p0.pin_cnf(0)
774+
.write(|w| w.set_mcusel(pac::gpio::vals::Mcusel::PERIPHERAL));
775+
p0.pin_cnf(1)
776+
.write(|w| w.set_mcusel(pac::gpio::vals::Mcusel::PERIPHERAL));
777+
}
778+
r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO));
779+
}
780+
}
726781
#[cfg(feature = "_nrf91")]
727782
match config.lfclk_source {
728783
config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)),

0 commit comments

Comments
 (0)