diff options
| -rw-r--r-- | .github/workflows/rust.yml | 3 | ||||
| -rw-r--r-- | embassy-nrf/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/chips/nrf9160.rs | 248 | ||||
| -rw-r--r-- | embassy-nrf/src/gpio.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 17 | ||||
| -rw-r--r-- | embassy-nrf/src/lib.rs | 16 | ||||
| -rw-r--r-- | embassy-nrf/src/ppi.rs | 38 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 58 | ||||
| -rw-r--r-- | embassy-nrf/src/wdt.rs | 7 | ||||
| -rw-r--r-- | rust-toolchain.toml | 2 |
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"] | |||
| 25 | nrf52832 = ["nrf52832-pac"] | 25 | nrf52832 = ["nrf52832-pac"] |
| 26 | nrf52833 = ["nrf52833-pac"] | 26 | nrf52833 = ["nrf52833-pac"] |
| 27 | nrf52840 = ["nrf52840-pac"] | 27 | nrf52840 = ["nrf52840-pac"] |
| 28 | nrf9160 = ["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" ] } | |||
| 55 | nrf52832-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } | 56 | nrf52832-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } |
| 56 | nrf52833-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } | 57 | nrf52833-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } |
| 57 | nrf52840-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } | 58 | nrf52840-pac = { version = "0.10.1", optional = true, features = [ "rt" ] } |
| 59 | nrf9160-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)] | ||
| 2 | pub 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. | ||
| 29 | pub const EASY_DMA_SIZE: usize = (1 << 13) - 1; | ||
| 30 | pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; | ||
| 31 | |||
| 32 | embassy_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 | |||
| 130 | impl_uarte!(UARTETWISPI0, UARTE0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); | ||
| 131 | impl_uarte!(UARTETWISPI1, UARTE1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); | ||
| 132 | impl_uarte!(UARTETWISPI2, UARTE2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); | ||
| 133 | impl_uarte!(UARTETWISPI3, UARTE3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); | ||
| 134 | |||
| 135 | impl_spim!(UARTETWISPI0, SPIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); | ||
| 136 | impl_spim!(UARTETWISPI1, SPIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); | ||
| 137 | impl_spim!(UARTETWISPI2, SPIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); | ||
| 138 | impl_spim!(UARTETWISPI3, SPIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); | ||
| 139 | |||
| 140 | impl_twim!(UARTETWISPI0, TWIM0_NS, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); | ||
| 141 | impl_twim!(UARTETWISPI1, TWIM1_NS, UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); | ||
| 142 | impl_twim!(UARTETWISPI2, TWIM2_NS, UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); | ||
| 143 | impl_twim!(UARTETWISPI3, TWIM3_NS, UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); | ||
| 144 | |||
| 145 | impl_pwm!(PWM0, PWM0_NS, PWM0); | ||
| 146 | impl_pwm!(PWM1, PWM1_NS, PWM1); | ||
| 147 | impl_pwm!(PWM2, PWM2_NS, PWM2); | ||
| 148 | impl_pwm!(PWM3, PWM3_NS, PWM3); | ||
| 149 | |||
| 150 | impl_timer!(TIMER0, TIMER0_NS, TIMER0); | ||
| 151 | impl_timer!(TIMER1, TIMER1_NS, TIMER1); | ||
| 152 | impl_timer!(TIMER2, TIMER2_NS, TIMER2); | ||
| 153 | |||
| 154 | impl_pin!(P0_00, 0, 0); | ||
| 155 | impl_pin!(P0_01, 0, 1); | ||
| 156 | impl_pin!(P0_02, 0, 2); | ||
| 157 | impl_pin!(P0_03, 0, 3); | ||
| 158 | impl_pin!(P0_04, 0, 4); | ||
| 159 | impl_pin!(P0_05, 0, 5); | ||
| 160 | impl_pin!(P0_06, 0, 6); | ||
| 161 | impl_pin!(P0_07, 0, 7); | ||
| 162 | impl_pin!(P0_08, 0, 8); | ||
| 163 | impl_pin!(P0_09, 0, 9); | ||
| 164 | impl_pin!(P0_10, 0, 10); | ||
| 165 | impl_pin!(P0_11, 0, 11); | ||
| 166 | impl_pin!(P0_12, 0, 12); | ||
| 167 | impl_pin!(P0_13, 0, 13); | ||
| 168 | impl_pin!(P0_14, 0, 14); | ||
| 169 | impl_pin!(P0_15, 0, 15); | ||
| 170 | impl_pin!(P0_16, 0, 16); | ||
| 171 | impl_pin!(P0_17, 0, 17); | ||
| 172 | impl_pin!(P0_18, 0, 18); | ||
| 173 | impl_pin!(P0_19, 0, 19); | ||
| 174 | impl_pin!(P0_20, 0, 20); | ||
| 175 | impl_pin!(P0_21, 0, 21); | ||
| 176 | impl_pin!(P0_22, 0, 22); | ||
| 177 | impl_pin!(P0_23, 0, 23); | ||
| 178 | impl_pin!(P0_24, 0, 24); | ||
| 179 | impl_pin!(P0_25, 0, 25); | ||
| 180 | impl_pin!(P0_26, 0, 26); | ||
| 181 | impl_pin!(P0_27, 0, 27); | ||
| 182 | impl_pin!(P0_28, 0, 28); | ||
| 183 | impl_pin!(P0_29, 0, 29); | ||
| 184 | impl_pin!(P0_30, 0, 30); | ||
| 185 | impl_pin!(P0_31, 0, 31); | ||
| 186 | |||
| 187 | impl_ppi_channel!(PPI_CH0, 0); | ||
| 188 | impl_ppi_channel!(PPI_CH1, 1); | ||
| 189 | impl_ppi_channel!(PPI_CH2, 2); | ||
| 190 | impl_ppi_channel!(PPI_CH3, 3); | ||
| 191 | impl_ppi_channel!(PPI_CH4, 4); | ||
| 192 | impl_ppi_channel!(PPI_CH5, 5); | ||
| 193 | impl_ppi_channel!(PPI_CH6, 6); | ||
| 194 | impl_ppi_channel!(PPI_CH7, 7); | ||
| 195 | impl_ppi_channel!(PPI_CH8, 8); | ||
| 196 | impl_ppi_channel!(PPI_CH9, 9); | ||
| 197 | impl_ppi_channel!(PPI_CH10, 10); | ||
| 198 | impl_ppi_channel!(PPI_CH11, 11); | ||
| 199 | impl_ppi_channel!(PPI_CH12, 12); | ||
| 200 | impl_ppi_channel!(PPI_CH13, 13); | ||
| 201 | impl_ppi_channel!(PPI_CH14, 14); | ||
| 202 | impl_ppi_channel!(PPI_CH15, 15); | ||
| 203 | |||
| 204 | impl_saadc_input!(P0_13, ANALOGINPUT0); | ||
| 205 | impl_saadc_input!(P0_14, ANALOGINPUT1); | ||
| 206 | impl_saadc_input!(P0_15, ANALOGINPUT2); | ||
| 207 | impl_saadc_input!(P0_16, ANALOGINPUT3); | ||
| 208 | impl_saadc_input!(P0_17, ANALOGINPUT4); | ||
| 209 | impl_saadc_input!(P0_18, ANALOGINPUT5); | ||
| 210 | impl_saadc_input!(P0_19, ANALOGINPUT6); | ||
| 211 | impl_saadc_input!(P0_20, ANALOGINPUT7); | ||
| 212 | |||
| 213 | pub 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)] |
| 19 | pub enum Port { | 19 | pub 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] | ||
| 74 | fn GPIOTE() { | ||
| 75 | unsafe { handle_gpiote_interrupt() }; | ||
| 76 | } | ||
| 77 | |||
| 78 | #[cfg(feature = "nrf9160")] | ||
| 68 | #[interrupt] | 79 | #[interrupt] |
| 69 | unsafe fn GPIOTE() { | 80 | fn GPIOTE1() { |
| 81 | unsafe { handle_gpiote_interrupt() }; | ||
| 82 | } | ||
| 83 | |||
| 84 | unsafe 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; | |||
| 34 | pub mod pwm; | 34 | pub mod pwm; |
| 35 | #[cfg(feature = "nrf52840")] | 35 | #[cfg(feature = "nrf52840")] |
| 36 | pub mod qspi; | 36 | pub mod qspi; |
| 37 | #[cfg(not(feature = "nrf9160"))] | ||
| 37 | pub mod rng; | 38 | pub mod rng; |
| 38 | #[cfg(not(feature = "nrf52820"))] | 39 | #[cfg(not(feature = "nrf52820"))] |
| 39 | pub mod saadc; | 40 | pub 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"] |
| 67 | mod chip; | 68 | mod chip; |
| 69 | #[cfg(feature = "nrf9160")] | ||
| 70 | #[path = "chips/nrf9160.rs"] | ||
| 71 | mod chip; | ||
| 68 | 72 | ||
| 69 | pub use chip::EASY_DMA_SIZE; | 73 | pub 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"))] |
| 74 | pub(crate) use chip::pac; | 78 | pub(crate) use chip::pac; |
| 75 | 79 | ||
| 80 | use crate::pac::CLOCK; | ||
| 76 | pub use chip::{peripherals, Peripherals}; | 81 | pub use chip::{peripherals, Peripherals}; |
| 77 | 82 | ||
| 78 | pub mod interrupt { | 83 | pub 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 | ||
| 14 | use crate::{pac, peripherals}; | ||
| 14 | use core::marker::PhantomData; | 15 | use core::marker::PhantomData; |
| 15 | use core::ptr::NonNull; | 16 | use core::ptr::NonNull; |
| 16 | use embassy::util::Unborrow; | 17 | use embassy::util::Unborrow; |
| 17 | use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; | 18 | use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; |
| 18 | 19 | ||
| 19 | use crate::{pac, peripherals}; | ||
| 20 | |||
| 21 | // ====================== | 20 | // ====================== |
| 22 | // driver | 21 | // driver |
| 23 | 22 | ||
| @@ -29,11 +28,13 @@ pub struct Ppi<'d, C: Channel> { | |||
| 29 | impl<'d, C: Channel> Ppi<'d, C> { | 28 | impl<'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 | ||
| 73 | impl<'d, C: Channel> Drop for Ppi<'d, C> { | 87 | impl<'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"))] | ||
| 79 | impl<'d, C: ConfigurableChannel> Ppi<'d, C> { | 94 | impl<'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")] | ||
| 113 | impl<'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] |
| 4 | channel = "nightly-2021-08-18" | 4 | channel = "nightly-2021-08-18" |
| 5 | components = [ "rust-src", "rustfmt" ] | 5 | components = [ "rust-src", "rustfmt" ] |
| 6 | targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "wasm32-unknown-unknown" ] | 6 | targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabihf", "thumbv8m.main-none-eabihf", "wasm32-unknown-unknown" ] |
