aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/rust.yml3
-rw-r--r--embassy-nrf/Cargo.toml2
-rw-r--r--embassy-nrf/src/chips/nrf9160.rs248
-rw-r--r--embassy-nrf/src/gpio.rs2
-rw-r--r--embassy-nrf/src/gpiote.rs17
-rw-r--r--embassy-nrf/src/lib.rs16
-rw-r--r--embassy-nrf/src/ppi.rs38
-rw-r--r--embassy-nrf/src/uarte.rs58
-rw-r--r--embassy-nrf/src/wdt.rs7
-rw-r--r--rust-toolchain.toml2
10 files changed, 381 insertions, 12 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index e33a40ef3..ff30a09a7 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -55,6 +55,9 @@ jobs:
55 target: thumbv7em-none-eabi 55 target: thumbv7em-none-eabi
56 features: nrf52833 56 features: nrf52833
57 - package: embassy-nrf 57 - package: embassy-nrf
58 target: thumbv8m.main-none-eabihf
59 features: nrf9160
60 - package: embassy-nrf
58 target: thumbv7em-none-eabi 61 target: thumbv7em-none-eabi
59 features: nrf52840 62 features: nrf52840
60 - package: embassy-nrf 63 - package: embassy-nrf
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index d472069e7..7c5f8d32b 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -25,6 +25,7 @@ nrf52820 = ["nrf52820-pac"]
25nrf52832 = ["nrf52832-pac"] 25nrf52832 = ["nrf52832-pac"]
26nrf52833 = ["nrf52833-pac"] 26nrf52833 = ["nrf52833-pac"]
27nrf52840 = ["nrf52840-pac"] 27nrf52840 = ["nrf52840-pac"]
28nrf9160 = ["nrf9160-pac"]
28 29
29# Features starting with `_` are for internal use only. They're not intended 30# Features starting with `_` are for internal use only. They're not intended
30# to be enabled by other crates, and are not covered by semver guarantees. 31# 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" ] }
55nrf52832-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } 56nrf52832-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
56nrf52833-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } 57nrf52833-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
57nrf52840-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } 58nrf52840-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
59nrf9160-pac = { version = "0.10.1", optional = true, features = [ "rt" ] }
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs
new file mode 100644
index 000000000..42053d081
--- /dev/null
+++ b/embassy-nrf/src/chips/nrf9160.rs
@@ -0,0 +1,248 @@
1#[allow(unused_imports)]
2pub mod pac {
3 // The nRF9160 has a secure and non-secure (NS) mode.
4 // For now we only support the NS mode, but those peripherals have `_ns` appended to them.
5 // To avoid cfg spam, weŕe going to rename the ones we use here.
6 #[rustfmt::skip]
7 pub(crate) use nrf9160_pac::{
8 p0_ns as p0,
9 pwm0_ns as pwm0,
10 rtc0_ns as rtc0,
11 spim0_ns as spim0,
12 timer0_ns as timer0,
13 twim0_ns as twim0,
14 uarte0_ns as uarte0,
15 DPPIC_NS as PPI,
16 GPIOTE1_NS as GPIOTE,
17 P0_NS as P0,
18 RTC1_NS as RTC1,
19 WDT_NS as WDT,
20 saadc_ns as saadc,
21 SAADC_NS as SAADC,
22 CLOCK_NS as CLOCK,
23 };
24
25 pub use nrf9160_pac::*;
26}
27
28/// The maximum buffer size that the EasyDMA can send/recv in one operation.
29pub const EASY_DMA_SIZE: usize = (1 << 13) - 1;
30pub const FORCE_COPY_BUFFER_SIZE: usize = 1024;
31
32embassy_hal_common::peripherals! {
33 // RTC
34 RTC0,
35 RTC1,
36
37 // WDT
38 WDT,
39
40 // UARTE, TWI & SPI
41 UARTETWISPI0,
42 UARTETWISPI1,
43 UARTETWISPI2,
44 UARTETWISPI3,
45
46 // SAADC
47 SAADC,
48
49 // PWM
50 PWM0,
51 PWM1,
52 PWM2,
53 PWM3,
54
55 // TIMER
56 TIMER0,
57 TIMER1,
58 TIMER2,
59
60 // GPIOTE
61 GPIOTE_CH0,
62 GPIOTE_CH1,
63 GPIOTE_CH2,
64 GPIOTE_CH3,
65 GPIOTE_CH4,
66 GPIOTE_CH5,
67 GPIOTE_CH6,
68 GPIOTE_CH7,
69
70 // PPI
71 PPI_CH0,
72 PPI_CH1,
73 PPI_CH2,
74 PPI_CH3,
75 PPI_CH4,
76 PPI_CH5,
77 PPI_CH6,
78 PPI_CH7,
79 PPI_CH8,
80 PPI_CH9,
81 PPI_CH10,
82 PPI_CH11,
83 PPI_CH12,
84 PPI_CH13,
85 PPI_CH14,
86 PPI_CH15,
87
88 PPI_GROUP0,
89 PPI_GROUP1,
90 PPI_GROUP2,
91 PPI_GROUP3,
92 PPI_GROUP4,
93 PPI_GROUP5,
94
95 // GPIO port 0
96 P0_00,
97 P0_01,
98 P0_02,
99 P0_03,
100 P0_04,
101 P0_05,
102 P0_06,
103 P0_07,
104 P0_08,
105 P0_09,
106 P0_10,
107 P0_11,
108 P0_12,
109 P0_13,
110 P0_14,
111 P0_15,
112 P0_16,
113 P0_17,
114 P0_18,
115 P0_19,
116 P0_20,
117 P0_21,
118 P0_22,
119 P0_23,
120 P0_24,
121 P0_25,
122 P0_26,
123 P0_27,
124 P0_28,
125 P0_29,
126 P0_30,
127 P0_31,
128}
129
130impl_uarte!(UARTETWISPI0, UARTE0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
131impl_uarte!(UARTETWISPI1, UARTE1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
132impl_uarte!(UARTETWISPI2, UARTE2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
133impl_uarte!(UARTETWISPI3, UARTE3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
134
135impl_spim!(UARTETWISPI0, SPIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
136impl_spim!(UARTETWISPI1, SPIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
137impl_spim!(UARTETWISPI2, SPIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
138impl_spim!(UARTETWISPI3, SPIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
139
140impl_twim!(UARTETWISPI0, TWIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
141impl_twim!(UARTETWISPI1, TWIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
142impl_twim!(UARTETWISPI2, TWIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
143impl_twim!(UARTETWISPI3, TWIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
144
145impl_pwm!(PWM0, PWM0_NS, PWM0);
146impl_pwm!(PWM1, PWM1_NS, PWM1);
147impl_pwm!(PWM2, PWM2_NS, PWM2);
148impl_pwm!(PWM3, PWM3_NS, PWM3);
149
150impl_timer!(TIMER0, TIMER0_NS, TIMER0);
151impl_timer!(TIMER1, TIMER1_NS, TIMER1);
152impl_timer!(TIMER2, TIMER2_NS, TIMER2);
153
154impl_pin!(P0_00, 0, 0);
155impl_pin!(P0_01, 0, 1);
156impl_pin!(P0_02, 0, 2);
157impl_pin!(P0_03, 0, 3);
158impl_pin!(P0_04, 0, 4);
159impl_pin!(P0_05, 0, 5);
160impl_pin!(P0_06, 0, 6);
161impl_pin!(P0_07, 0, 7);
162impl_pin!(P0_08, 0, 8);
163impl_pin!(P0_09, 0, 9);
164impl_pin!(P0_10, 0, 10);
165impl_pin!(P0_11, 0, 11);
166impl_pin!(P0_12, 0, 12);
167impl_pin!(P0_13, 0, 13);
168impl_pin!(P0_14, 0, 14);
169impl_pin!(P0_15, 0, 15);
170impl_pin!(P0_16, 0, 16);
171impl_pin!(P0_17, 0, 17);
172impl_pin!(P0_18, 0, 18);
173impl_pin!(P0_19, 0, 19);
174impl_pin!(P0_20, 0, 20);
175impl_pin!(P0_21, 0, 21);
176impl_pin!(P0_22, 0, 22);
177impl_pin!(P0_23, 0, 23);
178impl_pin!(P0_24, 0, 24);
179impl_pin!(P0_25, 0, 25);
180impl_pin!(P0_26, 0, 26);
181impl_pin!(P0_27, 0, 27);
182impl_pin!(P0_28, 0, 28);
183impl_pin!(P0_29, 0, 29);
184impl_pin!(P0_30, 0, 30);
185impl_pin!(P0_31, 0, 31);
186
187impl_ppi_channel!(PPI_CH0, 0);
188impl_ppi_channel!(PPI_CH1, 1);
189impl_ppi_channel!(PPI_CH2, 2);
190impl_ppi_channel!(PPI_CH3, 3);
191impl_ppi_channel!(PPI_CH4, 4);
192impl_ppi_channel!(PPI_CH5, 5);
193impl_ppi_channel!(PPI_CH6, 6);
194impl_ppi_channel!(PPI_CH7, 7);
195impl_ppi_channel!(PPI_CH8, 8);
196impl_ppi_channel!(PPI_CH9, 9);
197impl_ppi_channel!(PPI_CH10, 10);
198impl_ppi_channel!(PPI_CH11, 11);
199impl_ppi_channel!(PPI_CH12, 12);
200impl_ppi_channel!(PPI_CH13, 13);
201impl_ppi_channel!(PPI_CH14, 14);
202impl_ppi_channel!(PPI_CH15, 15);
203
204impl_saadc_input!(P0_13, ANALOGINPUT0);
205impl_saadc_input!(P0_14, ANALOGINPUT1);
206impl_saadc_input!(P0_15, ANALOGINPUT2);
207impl_saadc_input!(P0_16, ANALOGINPUT3);
208impl_saadc_input!(P0_17, ANALOGINPUT4);
209impl_saadc_input!(P0_18, ANALOGINPUT5);
210impl_saadc_input!(P0_19, ANALOGINPUT6);
211impl_saadc_input!(P0_20, ANALOGINPUT7);
212
213pub mod irqs {
214 use crate::pac::Interrupt as InterruptEnum;
215 use embassy_macros::interrupt_declare as declare;
216
217 declare!(SPU);
218 declare!(CLOCK_POWER);
219 declare!(UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
220 declare!(UARTE1_SPIM1_SPIS1_TWIM1_TWIS1);
221 declare!(UARTE2_SPIM2_SPIS2_TWIM2_TWIS2);
222 declare!(UARTE3_SPIM3_SPIS3_TWIM3_TWIS3);
223 declare!(GPIOTE0);
224 declare!(SAADC);
225 declare!(TIMER0);
226 declare!(TIMER1);
227 declare!(TIMER2);
228 declare!(RTC0);
229 declare!(RTC1);
230 declare!(WDT);
231 declare!(EGU0);
232 declare!(EGU1);
233 declare!(EGU2);
234 declare!(EGU3);
235 declare!(EGU4);
236 declare!(EGU5);
237 declare!(PWM0);
238 declare!(PWM1);
239 declare!(PWM2);
240 declare!(PDM);
241 declare!(PWM3);
242 declare!(I2S);
243 declare!(IPC);
244 declare!(FPU);
245 declare!(GPIOTE1);
246 declare!(KMU);
247 declare!(CRYPTOCELL);
248}
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index e30df7e7e..be0fac2b0 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -17,7 +17,7 @@ use self::sealed::Pin as _;
17/// A GPIO port with up to 32 pins. 17/// A GPIO port with up to 32 pins.
18#[derive(Debug, Eq, PartialEq)] 18#[derive(Debug, Eq, PartialEq)]
19pub enum Port { 19pub enum Port {
20 /// Port 0, available on all nRF52 and nRF51 MCUs. 20 /// Port 0, available on nRF9160 and all nRF52 and nRF51 MCUs.
21 Port0, 21 Port0,
22 22
23 /// Port 1, only available on some nRF52 MCUs. 23 /// Port 1, only available on some nRF52 MCUs.
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 25d09db4e..bab49cebb 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -55,7 +55,11 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
55 55
56 // Enable interrupts 56 // Enable interrupts
57 57
58 #[cfg(not(feature = "nrf9160"))]
58 let irq = unsafe { interrupt::GPIOTE::steal() }; 59 let irq = unsafe { interrupt::GPIOTE::steal() };
60 #[cfg(feature = "nrf9160")]
61 let irq = unsafe { interrupt::GPIOTE1::steal() };
62
59 irq.unpend(); 63 irq.unpend();
60 irq.set_priority(irq_prio); 64 irq.set_priority(irq_prio);
61 irq.enable(); 65 irq.enable();
@@ -65,8 +69,19 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
65 g.intenset.write(|w| w.port().set()); 69 g.intenset.write(|w| w.port().set());
66} 70}
67 71
72#[cfg(not(feature = "nrf9160"))]
73#[interrupt]
74fn GPIOTE() {
75 unsafe { handle_gpiote_interrupt() };
76}
77
78#[cfg(feature = "nrf9160")]
68#[interrupt] 79#[interrupt]
69unsafe fn GPIOTE() { 80fn GPIOTE1() {
81 unsafe { handle_gpiote_interrupt() };
82}
83
84unsafe fn handle_gpiote_interrupt() {
70 let g = &*pac::GPIOTE::ptr(); 85 let g = &*pac::GPIOTE::ptr();
71 86
72 for i in 0..CHANNEL_COUNT { 87 for i in 0..CHANNEL_COUNT {
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 9a0e9c3a1..00c719a17 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -34,6 +34,7 @@ pub mod ppi;
34pub mod pwm; 34pub mod pwm;
35#[cfg(feature = "nrf52840")] 35#[cfg(feature = "nrf52840")]
36pub mod qspi; 36pub mod qspi;
37#[cfg(not(feature = "nrf9160"))]
37pub mod rng; 38pub mod rng;
38#[cfg(not(feature = "nrf52820"))] 39#[cfg(not(feature = "nrf52820"))]
39pub mod saadc; 40pub mod saadc;
@@ -65,6 +66,9 @@ mod chip;
65#[cfg(feature = "nrf52840")] 66#[cfg(feature = "nrf52840")]
66#[path = "chips/nrf52840.rs"] 67#[path = "chips/nrf52840.rs"]
67mod chip; 68mod chip;
69#[cfg(feature = "nrf9160")]
70#[path = "chips/nrf9160.rs"]
71mod chip;
68 72
69pub use chip::EASY_DMA_SIZE; 73pub use chip::EASY_DMA_SIZE;
70 74
@@ -73,6 +77,7 @@ pub use chip::pac;
73#[cfg(not(feature = "unstable-pac"))] 77#[cfg(not(feature = "unstable-pac"))]
74pub(crate) use chip::pac; 78pub(crate) use chip::pac;
75 79
80use crate::pac::CLOCK;
76pub use chip::{peripherals, Peripherals}; 81pub use chip::{peripherals, Peripherals};
77 82
78pub mod interrupt { 83pub mod interrupt {
@@ -91,9 +96,12 @@ pub mod config {
91 96
92 pub enum LfclkSource { 97 pub enum LfclkSource {
93 InternalRC, 98 InternalRC,
99 #[cfg(not(feature = "nrf9160"))]
94 Synthesized, 100 Synthesized,
95 ExternalXtal, 101 ExternalXtal,
102 #[cfg(not(feature = "nrf9160"))]
96 ExternalLowSwing, 103 ExternalLowSwing,
104 #[cfg(not(feature = "nrf9160"))]
97 ExternalFullSwing, 105 ExternalFullSwing,
98 } 106 }
99 107
@@ -129,7 +137,7 @@ pub fn init(config: config::Config) -> Peripherals {
129 // before doing anything important. 137 // before doing anything important.
130 let peripherals = Peripherals::take(); 138 let peripherals = Peripherals::take();
131 139
132 let r = unsafe { &*pac::CLOCK::ptr() }; 140 let r = unsafe { &*CLOCK::ptr() };
133 141
134 // Start HFCLK. 142 // Start HFCLK.
135 match config.hfclk_source { 143 match config.hfclk_source {
@@ -143,6 +151,7 @@ pub fn init(config: config::Config) -> Peripherals {
143 } 151 }
144 152
145 // Configure LFCLK. 153 // Configure LFCLK.
154 #[cfg(not(feature = "nrf9160"))]
146 match config.lfclk_source { 155 match config.lfclk_source {
147 config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()), 156 config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()),
148 config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()), 157 config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()),
@@ -162,6 +171,11 @@ pub fn init(config: config::Config) -> Peripherals {
162 w 171 w
163 }), 172 }),
164 } 173 }
174 #[cfg(feature = "nrf9160")]
175 match config.lfclk_source {
176 config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().lfrc()),
177 config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().lfxo()),
178 }
165 179
166 // Start LFCLK. 180 // Start LFCLK.
167 // Datasheet says this could take 100us from synth source 181 // Datasheet says this could take 100us from synth source
diff --git a/embassy-nrf/src/ppi.rs b/embassy-nrf/src/ppi.rs
index 1b12b1e95..f5e06c69f 100644
--- a/embassy-nrf/src/ppi.rs
+++ b/embassy-nrf/src/ppi.rs
@@ -11,13 +11,12 @@
11//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task 11//! On nRF52 devices, there is also a fork task endpoint, where the user can configure one more task
12//! to be triggered by the same event, even fixed PPI channels have a configurable fork task. 12//! to be triggered by the same event, even fixed PPI channels have a configurable fork task.
13 13
14use crate::{pac, peripherals};
14use core::marker::PhantomData; 15use core::marker::PhantomData;
15use core::ptr::NonNull; 16use core::ptr::NonNull;
16use embassy::util::Unborrow; 17use embassy::util::Unborrow;
17use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; 18use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
18 19
19use crate::{pac, peripherals};
20
21// ====================== 20// ======================
22// driver 21// driver
23 22
@@ -29,11 +28,13 @@ pub struct Ppi<'d, C: Channel> {
29impl<'d, C: Channel> Ppi<'d, C> { 28impl<'d, C: Channel> Ppi<'d, C> {
30 pub fn new(ch: impl Unborrow<Target = C> + 'd) -> Self { 29 pub fn new(ch: impl Unborrow<Target = C> + 'd) -> Self {
31 unborrow!(ch); 30 unborrow!(ch);
31
32 #[allow(unused_mut)]
32 let mut this = Self { 33 let mut this = Self {
33 ch, 34 ch,
34 phantom: PhantomData, 35 phantom: PhantomData,
35 }; 36 };
36 #[cfg(not(feature = "nrf51"))] 37 #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
37 this.clear_fork_task(); 38 this.clear_fork_task();
38 this 39 this
39 } 40 }
@@ -52,7 +53,7 @@ impl<'d, C: Channel> Ppi<'d, C> {
52 .write(|w| unsafe { w.bits(1 << self.ch.number()) }); 53 .write(|w| unsafe { w.bits(1 << self.ch.number()) });
53 } 54 }
54 55
55 #[cfg(not(feature = "nrf51"))] 56 #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
56 /// Sets the fork task that must be triggered when the configured event occurs. The user must 57 /// Sets the fork task that must be triggered when the configured event occurs. The user must
57 /// provide a reference to the task. 58 /// provide a reference to the task.
58 pub fn set_fork_task(&mut self, task: Task) { 59 pub fn set_fork_task(&mut self, task: Task) {
@@ -62,12 +63,25 @@ impl<'d, C: Channel> Ppi<'d, C> {
62 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) }) 63 .write(|w| unsafe { w.bits(task.0.as_ptr() as u32) })
63 } 64 }
64 65
65 #[cfg(not(feature = "nrf51"))] 66 #[cfg(not(any(feature = "nrf51", feature = "nrf9160")))]
66 /// Clear the fork task endpoint. Previously set task will no longer be triggered. 67 /// Clear the fork task endpoint. Previously set task will no longer be triggered.
67 pub fn clear_fork_task(&mut self) { 68 pub fn clear_fork_task(&mut self) {
68 let r = unsafe { &*pac::PPI::ptr() }; 69 let r = unsafe { &*pac::PPI::ptr() };
69 r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) }) 70 r.fork[self.ch.number()].tep.write(|w| unsafe { w.bits(0) })
70 } 71 }
72
73 #[cfg(feature = "nrf9160")]
74 /// Sets the fork task that must be triggered when the configured event occurs. The user must
75 /// provide a reference to the task.
76 pub fn set_fork_task(&mut self, _task: Task) {
77 todo!("Tasks not yet implemented for nrf9160");
78 }
79
80 #[cfg(feature = "nrf9160")]
81 /// Clear the fork task endpoint. Previously set task will no longer be triggered.
82 pub fn clear_fork_task(&mut self) {
83 todo!("Tasks not yet implemented for nrf9160");
84 }
71} 85}
72 86
73impl<'d, C: Channel> Drop for Ppi<'d, C> { 87impl<'d, C: Channel> Drop for Ppi<'d, C> {
@@ -76,6 +90,7 @@ impl<'d, C: Channel> Drop for Ppi<'d, C> {
76 } 90 }
77} 91}
78 92
93#[cfg(not(feature = "nrf9160"))]
79impl<'d, C: ConfigurableChannel> Ppi<'d, C> { 94impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
80 /// Sets the task to be triggered when the configured event occurs. 95 /// Sets the task to be triggered when the configured event occurs.
81 pub fn set_task(&mut self, task: Task) { 96 pub fn set_task(&mut self, task: Task) {
@@ -94,6 +109,19 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
94 } 109 }
95} 110}
96 111
112#[cfg(feature = "nrf9160")]
113impl<'d, C: ConfigurableChannel> Ppi<'d, C> {
114 /// Sets the task to be triggered when the configured event occurs.
115 pub fn set_task(&mut self, _task: Task) {
116 todo!("Tasks not yet implemented for nrf9160")
117 }
118
119 /// Sets the event that will trigger the chosen task(s).
120 pub fn set_event(&mut self, _event: Event) {
121 todo!("Events not yet implemented for nrf9160")
122 }
123}
124
97// ====================== 125// ======================
98// traits 126// traits
99 127
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 320426060..024a86c91 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -68,8 +68,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
68 68
69 let r = T::regs(); 69 let r = T::regs();
70 70
71 assert!(r.enable.read().enable().is_disabled());
72
73 rxd.conf().write(|w| w.input().connect().drive().h0h1()); 71 rxd.conf().write(|w| w.input().connect().drive().h0h1());
74 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); 72 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
75 73
@@ -114,6 +112,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
114 irq.enable(); 112 irq.enable();
115 113
116 // Enable 114 // Enable
115 Self::apply_workaround_for_enable_anomaly();
117 r.enable.write(|w| w.enable().enabled()); 116 r.enable.write(|w| w.enable().enabled());
118 117
119 Self { 118 Self {
@@ -121,6 +120,61 @@ impl<'d, T: Instance> Uarte<'d, T> {
121 } 120 }
122 } 121 }
123 122
123 #[cfg(not(any(feature = "nrf9160", feature = "nrf5340")))]
124 fn apply_workaround_for_enable_anomaly() {
125 // Do nothing
126 }
127
128 #[cfg(any(feature = "nrf9160", feature = "nrf5340"))]
129 fn apply_workaround_for_enable_anomaly() {
130 use core::ops::Deref;
131
132 let r = T::regs();
133
134 // Apply workaround for anomalies:
135 // - nRF9160 - anomaly 23
136 // - nRF5340 - anomaly 44
137 let rxenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x564) as *const u32;
138 let txenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x568) as *const u32;
139
140 // NB Safety: This is taken from Nordic's driver -
141 // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
142 if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 {
143 r.tasks_stoptx.write(|w| unsafe { w.bits(1) });
144 }
145
146 // NB Safety: This is taken from Nordic's driver -
147 // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
148 if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 {
149 r.enable.write(|w| w.enable().enabled());
150 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
151
152 let mut workaround_succeded = false;
153 // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered.
154 // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured
155 // (resulting in 12 bits per data byte sent), this may take up to 40 ms.
156 for _ in 0..40000 {
157 // NB Safety: This is taken from Nordic's driver -
158 // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197
159 if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 {
160 workaround_succeded = true;
161 break;
162 } else {
163 // Need to sleep for 1us here
164 }
165 }
166
167 if !workaround_succeded {
168 panic!("Failed to apply workaround for UART");
169 }
170
171 let errors = r.errorsrc.read().bits();
172 // NB Safety: safe to write back the bits we just read to clear them
173 r.errorsrc.write(|w| unsafe { w.bits(errors) });
174 r.enable.write(|w| w.enable().disabled());
175 }
176 }
177
124 fn on_interrupt(_: *mut ()) { 178 fn on_interrupt(_: *mut ()) {
125 let r = T::regs(); 179 let r = T::regs();
126 let s = T::state(); 180 let s = T::state();
diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs
index cd62d0d60..eddfa7582 100644
--- a/embassy-nrf/src/wdt.rs
+++ b/embassy-nrf/src/wdt.rs
@@ -58,7 +58,12 @@ impl Watchdog {
58 let crv = config.timeout_ticks.max(MIN_TICKS); 58 let crv = config.timeout_ticks.max(MIN_TICKS);
59 let rren = (1u32 << N) - 1; 59 let rren = (1u32 << N) - 1;
60 60
61 if r.runstatus.read().runstatus().bit() { 61 #[cfg(not(feature = "nrf9160"))]
62 let runstatus = r.runstatus.read().runstatus().bit();
63 #[cfg(feature = "nrf9160")]
64 let runstatus = r.runstatus.read().runstatuswdt().bit();
65
66 if runstatus {
62 let curr_config = r.config.read(); 67 let curr_config = r.config.read();
63 if curr_config.halt().bit() != config.run_during_debug_halt 68 if curr_config.halt().bit() != config.run_during_debug_halt
64 || curr_config.sleep().bit() != config.run_during_sleep 69 || curr_config.sleep().bit() != config.run_during_sleep
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 8f3473433..00901f820 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -3,4 +3,4 @@
3[toolchain] 3[toolchain]
4channel = "nightly-2021-08-18" 4channel = "nightly-2021-08-18"
5components = [ "rust-src", "rustfmt" ] 5components = [ "rust-src", "rustfmt" ]
6targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "wasm32-unknown-unknown" ] 6targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ]