Merge #423
423: nRF9160 support r=Dirbaio a=diondokter - Created a chip file with all the peripherals, interrupts and peripheral implementations. - All peripherals now use an alias for the NS (non-secure) version of the nRF9160 version. - Implementations of peripherals that don't exist are ignored. - Most PPI functionality has been stubbed out because the nRF91 has the newer DPPI which is not compatible with the current API. (The channels are also set to not configurable, so they are kinda useless now, but in principle the stubs should never be called) Co-authored-by: Dion Dokter <dion@tweedegolf.com>
This commit is contained in:
commit
05bc4d198e
3
.github/workflows/rust.yml
vendored
3
.github/workflows/rust.yml
vendored
@ -54,6 +54,9 @@ jobs:
|
||||
- package: embassy-nrf
|
||||
target: thumbv7em-none-eabi
|
||||
features: nrf52833
|
||||
- package: embassy-nrf
|
||||
target: thumbv8m.main-none-eabihf
|
||||
features: nrf9160
|
||||
- package: embassy-nrf
|
||||
target: thumbv7em-none-eabi
|
||||
features: nrf52840
|
||||
|
@ -25,6 +25,7 @@ nrf52820 = ["nrf52820-pac"]
|
||||
nrf52832 = ["nrf52832-pac"]
|
||||
nrf52833 = ["nrf52833-pac"]
|
||||
nrf52840 = ["nrf52840-pac"]
|
||||
nrf9160 = ["nrf9160-pac"]
|
||||
|
||||
# Features starting with `_` are for internal use only. They're not intended
|
||||
# to be enabled by other crates, and are not covered by semver guarantees.
|
||||
@ -55,3 +56,4 @@ nrf52820-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||
nrf52832-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||
nrf52833-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||
nrf52840-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||
nrf9160-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
|
||||
|
248
embassy-nrf/src/chips/nrf9160.rs
Normal file
248
embassy-nrf/src/chips/nrf9160.rs
Normal file
@ -0,0 +1,248 @@
|
||||
#[allow(unused_imports)]
|
||||
pub mod pac {
|
||||
// The nRF9160 has a secure and non-secure (NS) mode.
|
||||
// For now we only support the NS mode, but those peripherals have `_ns` appended to them.
|
||||
// To avoid cfg spam, weŕe going to rename the ones we use here.
|
||||
#[rustfmt::skip]
|
||||
pub(crate) use nrf9160_pac::{
|
||||
p0_ns as p0,
|
||||
pwm0_ns as pwm0,
|
||||
rtc0_ns as rtc0,
|
||||
spim0_ns as spim0,
|
||||
timer0_ns as timer0,
|
||||
twim0_ns as twim0,
|
||||
uarte0_ns as uarte0,
|
||||
DPPIC_NS as PPI,
|
||||
GPIOTE1_NS as GPIOTE,
|
||||
P0_NS as P0,
|
||||
RTC1_NS as RTC1,
|
||||
WDT_NS as WDT,
|
||||
saadc_ns as saadc,
|
||||
SAADC_NS as SAADC,
|
||||
CLOCK_NS as CLOCK,
|
||||
};
|
||||
|
||||
pub use nrf9160_pac::*;
|
||||
}
|
||||
|
||||
/// The maximum buffer size that the EasyDMA can send/recv in one operation.
|
||||
pub const EASY_DMA_SIZE: usize = (1 << 13) - 1;
|
||||
pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
|
||||
|
||||
embassy_hal_common::peripherals! {
|
||||
// RTC
|
||||
RTC0,
|
||||
RTC1,
|
||||
|
||||
// WDT
|
||||
WDT,
|
||||
|
||||
// UARTE, TWI & SPI
|
||||
UARTETWISPI0,
|
||||
UARTETWISPI1,
|
||||
UARTETWISPI2,
|
||||
UARTETWISPI3,
|
||||
|
||||
// SAADC
|
||||
SAADC,
|
||||
|
||||
// PWM
|
||||
PWM0,
|
||||
PWM1,
|
||||
PWM2,
|
||||
PWM3,
|
||||
|
||||
// TIMER
|
||||
TIMER0,
|
||||
TIMER1,
|
||||
TIMER2,
|
||||
|
||||
// GPIOTE
|
||||
GPIOTE_CH0,
|
||||
GPIOTE_CH1,
|
||||
GPIOTE_CH2,
|
||||
GPIOTE_CH3,
|
||||
GPIOTE_CH4,
|
||||
GPIOTE_CH5,
|
||||
GPIOTE_CH6,
|
||||
GPIOTE_CH7,
|
||||
|
||||
// PPI
|
||||
PPI_CH0,
|
||||
PPI_CH1,
|
||||
PPI_CH2,
|
||||
PPI_CH3,
|
||||
PPI_CH4,
|
||||
PPI_CH5,
|
||||
PPI_CH6,
|
||||
PPI_CH7,
|
||||
PPI_CH8,
|
||||
PPI_CH9,
|
||||
PPI_CH10,
|
||||
PPI_CH11,
|
||||
PPI_CH12,
|
||||
PPI_CH13,
|
||||
PPI_CH14,
|
||||
PPI_CH15,
|
||||
|
||||
PPI_GROUP0,
|
||||
PPI_GROUP1,
|
||||
PPI_GROUP2,
|
||||
PPI_GROUP3,
|
||||
PPI_GROUP4,
|
||||
PPI_GROUP5,
|
||||
|
||||
// GPIO port 0
|
||||
P0_00,
|
||||
P0_01,
|
||||
P0_02,
|
||||
P0_03,
|
||||
P0_04,
|
||||
P0_05,
|
||||
P0_06,
|
||||
P0_07,
|
||||
P0_08,
|
||||
P0_09,
|
||||
P0_10,
|
||||
P0_11,
|
||||
P0_12,
|
||||
P0_13,
|
||||
P0_14,
|
||||
P0_15,
|
||||
P0_16,
|
||||
P0_17,
|
||||
P0_18,
|
||||
P0_19,
|
||||
P0_20,
|
||||
P0_21,
|
||||
P0_22,
|
||||
P0_23,
|
||||
P0_24,
|
||||
P0_25,
|
||||
P0_26,
|
||||
P0_27,
|
||||
P0_28,
|
||||
P0_29,
|
||||
P0_30,
|
||||
P0_31,
|
||||
}
|
||||
|
||||
impl_uarte!(UARTETWISPI0, UARTE0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
|
||||
impl_uarte!(UARTETWISPI1, UARTE1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
|
||||
impl_uarte!(UARTETWISPI2, UARTE2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
|
||||
impl_uarte!(UARTETWISPI3, UARTE3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
|
||||
|
||||
impl_spim!(UARTETWISPI0, SPIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
|
||||
impl_spim!(UARTETWISPI1, SPIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
|
||||
impl_spim!(UARTETWISPI2, SPIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
|
||||
impl_spim!(UARTETWISPI3, SPIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
|
||||
|
||||
impl_twim!(UARTETWISPI0, TWIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
|
||||
impl_twim!(UARTETWISPI1, TWIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
|
||||
impl_twim!(UARTETWISPI2, TWIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
|
||||
impl_twim!(UARTETWISPI3, TWIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
|
||||
|
||||
impl_pwm!(PWM0, PWM0_NS, PWM0);
|
||||
impl_pwm!(PWM1, PWM1_NS, PWM1);
|
||||
impl_pwm!(PWM2, PWM2_NS, PWM2);
|
||||
impl_pwm!(PWM3, PWM3_NS, PWM3);
|
||||
|
||||
impl_timer!(TIMER0, TIMER0_NS, TIMER0);
|
||||
impl_timer!(TIMER1, TIMER1_NS, TIMER1);
|
||||
impl_timer!(TIMER2, TIMER2_NS, TIMER2);
|
||||
|
||||
impl_pin!(P0_00, 0, 0);
|
||||
impl_pin!(P0_01, 0, 1);
|
||||
impl_pin!(P0_02, 0, 2);
|
||||
impl_pin!(P0_03, 0, 3);
|
||||
impl_pin!(P0_04, 0, 4);
|
||||
impl_pin!(P0_05, 0, 5);
|
||||
impl_pin!(P0_06, 0, 6);
|
||||
impl_pin!(P0_07, 0, 7);
|
||||
impl_pin!(P0_08, 0, 8);
|
||||
impl_pin!(P0_09, 0, 9);
|
||||
impl_pin!(P0_10, 0, 10);
|
||||
impl_pin!(P0_11, 0, 11);
|
||||
impl_pin!(P0_12, 0, 12);
|
||||
impl_pin!(P0_13, 0, 13);
|
||||
impl_pin!(P0_14, 0, 14);
|
||||
impl_pin!(P0_15, 0, 15);
|
||||
impl_pin!(P0_16, 0, 16);
|
||||
impl_pin!(P0_17, 0, 17);
|
||||
impl_pin!(P0_18, 0, 18);
|
||||
impl_pin!(P0_19, 0, 19);
|
||||
impl_pin!(P0_20, 0, 20);
|
||||
impl_pin!(P0_21, 0, 21);
|
||||
impl_pin!(P0_22, 0, 22);
|
||||
impl_pin!(P0_23, 0, 23);
|
||||
impl_pin!(P0_24, 0, 24);
|
||||
impl_pin!(P0_25, 0, 25);
|
||||
impl_pin!(P0_26, 0, 26);
|
||||
impl_pin!(P0_27, 0, 27);
|
||||
impl_pin!(P0_28, 0, 28);
|
||||
impl_pin!(P0_29, 0, 29);
|
||||
impl_pin!(P0_30, 0, 30);
|
||||
impl_pin!(P0_31, 0, 31);
|
||||
|
||||
impl_ppi_channel!(PPI_CH0, 0);
|
||||
impl_ppi_channel!(PPI_CH1, 1);
|
||||
impl_ppi_channel!(PPI_CH2, 2);
|
||||
impl_ppi_channel!(PPI_CH3, 3);
|
||||
impl_ppi_channel!(PPI_CH4, 4);
|
||||
impl_ppi_channel!(PPI_CH5, 5);
|
||||
impl_ppi_channel!(PPI_CH6, 6);
|
||||
impl_ppi_channel!(PPI_CH7, 7);
|
||||
impl_ppi_channel!(PPI_CH8, 8);
|
||||
impl_ppi_channel!(PPI_CH9, 9);
|
||||
impl_ppi_channel!(PPI_CH10, 10);
|
||||
impl_ppi_channel!(PPI_CH11, 11);
|
||||
impl_ppi_channel!(PPI_CH12, 12);
|
||||
impl_ppi_channel!(PPI_CH13, 13);
|
||||
impl_ppi_channel!(PPI_CH14, 14);
|
||||
impl_ppi_channel!(PPI_CH15, 15);
|
||||
|
||||
impl_saadc_input!(P0_13, ANALOGINPUT0);
|
||||
impl_saadc_input!(P0_14, ANALOGINPUT1);
|
||||
impl_saadc_input!(P0_15, ANALOGINPUT2);
|
||||
impl_saadc_input!(P0_16, ANALOGINPUT3);
|
||||
impl_saadc_input!(P0_17, ANALOGINPUT4);
|
||||
impl_saadc_input!(P0_18, ANALOGINPUT5);
|
||||
impl_saadc_input!(P0_19, ANALOGINPUT6);
|
||||
impl_saadc_input!(P0_20, ANALOGINPUT7);
|
||||
|
||||
pub mod irqs {
|
||||
use crate::pac::Interrupt as InterruptEnum;
|
||||
use embassy_macros::interrupt_declare as declare;
|
||||
|
||||
declare!(SPU);
|
||||
declare!(CLOCK_POWER);
|
||||
declare!(UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
|
||||
declare!(UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
|
||||
declare!(UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
|
||||
declare!(UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
|
||||
declare!(GPIOTE0);
|
||||
declare!(SAADC);
|
||||
declare!(TIMER0);
|
||||
declare!(TIMER1);
|
||||
declare!(TIMER2);
|
||||
declare!(RTC0);
|
||||
declare!(RTC1);
|
||||
declare!(WDT);
|
||||
declare!(EGU0);
|
||||
declare!(EGU1);
|
||||
declare!(EGU2);
|
||||
declare!(EGU3);
|
||||
declare!(EGU4);
|
||||
declare!(EGU5);
|
||||
declare!(PWM0);
|
||||
declare!(PWM1);
|
||||
declare!(PWM2);
|
||||
declare!(PDM);
|
||||
declare!(PWM3);
|
||||
declare!(I2S);
|
||||
declare!(IPC);
|
||||
declare!(FPU);
|
||||
declare!(GPIOTE1);
|
||||
declare!(KMU);
|
||||
declare!(CRYPTOCELL);
|
||||
}
|
@ -17,7 +17,7 @@ use self::sealed::Pin as _;
|
||||
/// A GPIO port with up to 32 pins.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum Port {
|
||||
/// Port 0, available on all nRF52 and nRF51 MCUs.
|
||||
/// Port 0, available on nRF9160 and all nRF52 and nRF51 MCUs.
|
||||
Port0,
|
||||
|
||||
/// Port 1, only available on some nRF52 MCUs.
|
||||
|
@ -55,7 +55,11 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
|
||||
|
||||
// Enable interrupts
|
||||
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
let irq = unsafe { interrupt::GPIOTE::steal() };
|
||||
#[cfg(feature = "nrf9160")]
|
||||
let irq = unsafe { interrupt::GPIOTE1::steal() };
|
||||
|
||||
irq.unpend();
|
||||
irq.set_priority(irq_prio);
|
||||
irq.enable();
|
||||
@ -65,8 +69,19 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
|
||||
g.intenset.write(|w| w.port().set());
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
#[interrupt]
|
||||
unsafe fn GPIOTE() {
|
||||
fn GPIOTE() {
|
||||
unsafe { handle_gpiote_interrupt() };
|
||||
}
|
||||
|
||||
#[cfg(feature = "nrf9160")]
|
||||
#[interrupt]
|
||||
fn GPIOTE1() {
|
||||
unsafe { handle_gpiote_interrupt() };
|
||||
}
|
||||
|
||||
unsafe fn handle_gpiote_interrupt() {
|
||||
let g = &*pac::GPIOTE::ptr();
|
||||
|
||||
for i in 0..CHANNEL_COUNT {
|
||||
|
@ -34,6 +34,7 @@ pub mod ppi;
|
||||
pub mod pwm;
|
||||
#[cfg(feature = "nrf52840")]
|
||||
pub mod qspi;
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
pub mod rng;
|
||||
#[cfg(not(feature = "nrf52820"))]
|
||||
pub mod saadc;
|
||||
@ -65,6 +66,9 @@ mod chip;
|
||||
#[cfg(feature = "nrf52840")]
|
||||
#[path = "chips/nrf52840.rs"]
|
||||
mod chip;
|
||||
#[cfg(feature = "nrf9160")]
|
||||
#[path = "chips/nrf9160.rs"]
|
||||
mod chip;
|
||||
|
||||
pub use chip::EASY_DMA_SIZE;
|
||||
|
||||
@ -73,6 +77,7 @@ pub use chip::pac;
|
||||
#[cfg(not(feature = "unstable-pac"))]
|
||||
pub(crate) use chip::pac;
|
||||
|
||||
use crate::pac::CLOCK;
|
||||
pub use chip::{peripherals, Peripherals};
|
||||
|
||||
pub mod interrupt {
|
||||
@ -91,9 +96,12 @@ pub mod config {
|
||||
|
||||
pub enum LfclkSource {
|
||||
InternalRC,
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
Synthesized,
|
||||
ExternalXtal,
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
ExternalLowSwing,
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
ExternalFullSwing,
|
||||
}
|
||||
|
||||
@ -129,7 +137,7 @@ pub fn init(config: config::Config) -> Peripherals {
|
||||
// before doing anything important.
|
||||
let peripherals = Peripherals::take();
|
||||
|
||||
let r = unsafe { &*pac::CLOCK::ptr() };
|
||||
let r = unsafe { &*CLOCK::ptr() };
|
||||
|
||||
// Start HFCLK.
|
||||
match config.hfclk_source {
|
||||
@ -143,6 +151,7 @@ pub fn init(config: config::Config) -> Peripherals {
|
||||
}
|
||||
|
||||
// Configure LFCLK.
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
match config.lfclk_source {
|
||||
config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()),
|
||||
config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()),
|
||||
@ -162,6 +171,11 @@ pub fn init(config: config::Config) -> Peripherals {
|
||||
w
|
||||
}),
|
||||
}
|
||||
#[cfg(feature = "nrf9160")]
|
||||
match config.lfclk_source {
|
||||
config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().lfrc()),
|
||||
config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().lfxo()),
|
||||
}
|
||||
|
||||
// Start LFCLK.
|
||||
// Datasheet says this could take 100us from synth source
|
||||
|
@ -11,13 +11,12 @@
|
||||
//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task
|
||||
//! to be triggered by the same event, even fixed PPI channels have a configurable fork task.
|
||||
|
||||
use crate::{pac, peripherals};
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr::NonNull;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||
|
||||
use crate::{pac, peripherals};
|
||||
|
||||
// ======================
|
||||
// driver
|
||||
|
||||
@ -29,11 +28,13 @@ pub struct Ppi<'d, C: Channel> {
|
||||
impl<'d, C: Channel> Ppi<'d, C> {
|
||||
pub fn new(ch: impl Unborrow<Target = C> + 'd) -> Self {
|
||||
unborrow!(ch);
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut this = Self {
|
||||
ch,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
#[cfg(not(feature = "nrf51"))]
|
||||
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
|
||||
this.clear_fork_task();
|
||||
this
|
||||
}
|
||||
@ -52,7 +53,7 @@ impl<'d, C: Channel> Ppi<'d, C> {
|
||||
.write(|w| unsafe { w.bits(1 << self.ch.number()) });
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nrf51"))]
|
||||
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
|
||||
/// Sets the fork task that must be triggered when the configured event occurs. The user must
|
||||
/// provide a reference to the task.
|
||||
pub fn set_fork_task(&mut self, task: Task) {
|
||||
@ -62,12 +63,25 @@ impl<'d, C: Channel> Ppi<'d, C> {
|
||||
.write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nrf51"))]
|
||||
#[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
|
||||
/// Clear the fork task endpoint. Previously set task will no longer be triggered.
|
||||
pub fn clear_fork_task(&mut self) {
|
||||
let r = unsafe { &*pac::PPI::ptr() };
|
||||
r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) })
|
||||
}
|
||||
|
||||
#[cfg(feature = "nrf9160")]
|
||||
/// Sets the fork task that must be triggered when the configured event occurs. The user must
|
||||
/// provide a reference to the task.
|
||||
pub fn set_fork_task(&mut self, _task: Task) {
|
||||
todo!("Tasks not yet implemented for nrf9160");
|
||||
}
|
||||
|
||||
#[cfg(feature = "nrf9160")]
|
||||
/// Clear the fork task endpoint. Previously set task will no longer be triggered.
|
||||
pub fn clear_fork_task(&mut self) {
|
||||
todo!("Tasks not yet implemented for nrf9160");
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, C: Channel> Drop for Ppi<'d, C> {
|
||||
@ -76,6 +90,7 @@ impl<'d, C: Channel> Drop for Ppi<'d, C> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
|
||||
/// Sets the task to be triggered when the configured event occurs.
|
||||
pub fn set_task(&mut self, task: Task) {
|
||||
@ -94,6 +109,19 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nrf9160")]
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
|
||||
/// Sets the task to be triggered when the configured event occurs.
|
||||
pub fn set_task(&mut self, _task: Task) {
|
||||
todo!("Tasks not yet implemented for nrf9160")
|
||||
}
|
||||
|
||||
/// Sets the event that will trigger the chosen task(s).
|
||||
pub fn set_event(&mut self, _event: Event) {
|
||||
todo!("Events not yet implemented for nrf9160")
|
||||
}
|
||||
}
|
||||
|
||||
// ======================
|
||||
// traits
|
||||
|
||||
|
@ -68,8 +68,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
assert!(r.enable.read().enable().is_disabled());
|
||||
|
||||
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
||||
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
||||
|
||||
@ -114,6 +112,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
irq.enable();
|
||||
|
||||
// Enable
|
||||
Self::apply_workaround_for_enable_anomaly();
|
||||
r.enable.write(|w| w.enable().enabled());
|
||||
|
||||
Self {
|
||||
@ -121,6 +120,61 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "nrf9160", feature = "nrf5340")))]
|
||||
fn apply_workaround_for_enable_anomaly() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "nrf9160", feature = "nrf5340"))]
|
||||
fn apply_workaround_for_enable_anomaly() {
|
||||
use core::ops::Deref;
|
||||
|
||||
let r = T::regs();
|
||||
|
||||
// Apply workaround for anomalies:
|
||||
// - nRF9160 - anomaly 23
|
||||
// - nRF5340 - anomaly 44
|
||||
let rxenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x564) as *const u32;
|
||||
let txenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x568) as *const u32;
|
||||
|
||||
// NB Safety: This is taken from Nordic's driver -
|
||||
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
|
||||
if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 {
|
||||
r.tasks_stoptx.write(|w| unsafe { w.bits(1) });
|
||||
}
|
||||
|
||||
// NB Safety: This is taken from Nordic's driver -
|
||||
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
|
||||
if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 {
|
||||
r.enable.write(|w| w.enable().enabled());
|
||||
r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
|
||||
|
||||
let mut workaround_succeded = false;
|
||||
// The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
|
||||
// On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
|
||||
// (resulting in 12 bits per data byte sent), this may take up to 40 ms.
|
||||
for _ in 0..40000 {
|
||||
// NB Safety: This is taken from Nordic's driver -
|
||||
// https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
|
||||
if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 {
|
||||
workaround_succeded = true;
|
||||
break;
|
||||
} else {
|
||||
// Need to sleep for 1us here
|
||||
}
|
||||
}
|
||||
|
||||
if !workaround_succeded {
|
||||
panic!("Failed to apply workaround for UART");
|
||||
}
|
||||
|
||||
let errors = r.errorsrc.read().bits();
|
||||
// NB Safety: safe to write back the bits we just read to clear them
|
||||
r.errorsrc.write(|w| unsafe { w.bits(errors) });
|
||||
r.enable.write(|w| w.enable().disabled());
|
||||
}
|
||||
}
|
||||
|
||||
fn on_interrupt(_: *mut ()) {
|
||||
let r = T::regs();
|
||||
let s = T::state();
|
||||
|
@ -58,7 +58,12 @@ impl Watchdog {
|
||||
let crv = config.timeout_ticks.max(MIN_TICKS);
|
||||
let rren = (1u32 << N) - 1;
|
||||
|
||||
if r.runstatus.read().runstatus().bit() {
|
||||
#[cfg(not(feature = "nrf9160"))]
|
||||
let runstatus = r.runstatus.read().runstatus().bit();
|
||||
#[cfg(feature = "nrf9160")]
|
||||
let runstatus = r.runstatus.read().runstatuswdt().bit();
|
||||
|
||||
if runstatus {
|
||||
let curr_config = r.config.read();
|
||||
if curr_config.halt().bit() != config.run_during_debug_halt
|
||||
|| curr_config.sleep().bit() != config.run_during_sleep
|
||||
|
@ -3,4 +3,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2021-08-18"
|
||||
components = [ "rust-src", "rustfmt" ]
|
||||
targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "wasm32-unknown-unknown" ]
|
||||
targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ]
|
||||
|
Loading…
Reference in New Issue
Block a user