diff options
58 files changed, 2160 insertions, 2297 deletions
diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml index 07a0c8886..98356c1ba 100644 --- a/embassy-net-nrf91/Cargo.toml +++ b/embassy-net-nrf91/Cargo.toml | |||
| @@ -17,7 +17,8 @@ log = [ "dep:log" ] | |||
| 17 | defmt = { version = "0.3", optional = true } | 17 | defmt = { version = "0.3", optional = true } |
| 18 | log = { version = "0.4.14", optional = true } | 18 | log = { version = "0.4.14", optional = true } |
| 19 | 19 | ||
| 20 | nrf9160-pac = { version = "0.12.0" } | 20 | nrf-pac = { git = "https://github.com/embassy-rs/nrf-pac", rev = "875a29629cc1c87aae00cfea647a956b3807d8be" } |
| 21 | cortex-m = "0.7.7" | ||
| 21 | 22 | ||
| 22 | embassy-time = { version = "0.3.1", path = "../embassy-time" } | 23 | embassy-time = { version = "0.3.1", path = "../embassy-time" } |
| 23 | embassy-sync = { version = "0.6.0", path = "../embassy-sync"} | 24 | embassy-sync = { version = "0.6.0", path = "../embassy-sync"} |
diff --git a/embassy-net-nrf91/src/lib.rs b/embassy-net-nrf91/src/lib.rs index 60cdc38c6..80d08f7f5 100644 --- a/embassy-net-nrf91/src/lib.rs +++ b/embassy-net-nrf91/src/lib.rs | |||
| @@ -17,12 +17,12 @@ use core::slice; | |||
| 17 | use core::sync::atomic::{compiler_fence, fence, Ordering}; | 17 | use core::sync::atomic::{compiler_fence, fence, Ordering}; |
| 18 | use core::task::{Poll, Waker}; | 18 | use core::task::{Poll, Waker}; |
| 19 | 19 | ||
| 20 | use cortex_m::peripheral::NVIC; | ||
| 20 | use embassy_sync::blocking_mutex::raw::NoopRawMutex; | 21 | use embassy_sync::blocking_mutex::raw::NoopRawMutex; |
| 21 | use embassy_sync::pipe; | 22 | use embassy_sync::pipe; |
| 22 | use embassy_sync::waitqueue::{AtomicWaker, WakerRegistration}; | 23 | use embassy_sync::waitqueue::{AtomicWaker, WakerRegistration}; |
| 23 | use heapless::Vec; | 24 | use heapless::Vec; |
| 24 | use pac::NVIC; | 25 | use {embassy_net_driver_channel as ch, nrf_pac as pac}; |
| 25 | use {embassy_net_driver_channel as ch, nrf9160_pac as pac}; | ||
| 26 | 26 | ||
| 27 | const RX_SIZE: usize = 8 * 1024; | 27 | const RX_SIZE: usize = 8 * 1024; |
| 28 | const TRACE_SIZE: usize = 16 * 1024; | 28 | const TRACE_SIZE: usize = 16 * 1024; |
| @@ -38,11 +38,9 @@ static WAKER: AtomicWaker = AtomicWaker::new(); | |||
| 38 | 38 | ||
| 39 | /// Call this function on IPC IRQ | 39 | /// Call this function on IPC IRQ |
| 40 | pub fn on_ipc_irq() { | 40 | pub fn on_ipc_irq() { |
| 41 | let ipc = unsafe { &*pac::IPC_NS::ptr() }; | ||
| 42 | |||
| 43 | trace!("irq"); | 41 | trace!("irq"); |
| 44 | 42 | ||
| 45 | ipc.inten.write(|w| w); | 43 | pac::IPC_NS.inten().write(|_| ()); |
| 46 | WAKER.wake(); | 44 | WAKER.wake(); |
| 47 | } | 45 | } |
| 48 | 46 | ||
| @@ -135,22 +133,21 @@ async fn new_internal<'a>( | |||
| 135 | "shmem must be in the lower 128kb of RAM" | 133 | "shmem must be in the lower 128kb of RAM" |
| 136 | ); | 134 | ); |
| 137 | 135 | ||
| 138 | let spu = unsafe { &*pac::SPU_S::ptr() }; | 136 | let spu = pac::SPU_S; |
| 139 | debug!("Setting IPC RAM as nonsecure..."); | 137 | debug!("Setting IPC RAM as nonsecure..."); |
| 140 | let region_start = (shmem_ptr as usize - 0x2000_0000) / SPU_REGION_SIZE; | 138 | let region_start = (shmem_ptr as usize - 0x2000_0000) / SPU_REGION_SIZE; |
| 141 | let region_end = region_start + shmem_len / SPU_REGION_SIZE; | 139 | let region_end = region_start + shmem_len / SPU_REGION_SIZE; |
| 142 | for i in region_start..region_end { | 140 | for i in region_start..region_end { |
| 143 | spu.ramregion[i].perm.write(|w| { | 141 | spu.ramregion(i).perm().write(|w| { |
| 144 | w.execute().set_bit(); | 142 | w.set_execute(true); |
| 145 | w.write().set_bit(); | 143 | w.set_write(true); |
| 146 | w.read().set_bit(); | 144 | w.set_read(true); |
| 147 | w.secattr().clear_bit(); | 145 | w.set_secattr(false); |
| 148 | w.lock().clear_bit(); | 146 | w.set_lock(false); |
| 149 | w | ||
| 150 | }) | 147 | }) |
| 151 | } | 148 | } |
| 152 | 149 | ||
| 153 | spu.periphid[42].perm.write(|w| w.secattr().non_secure()); | 150 | spu.periphid(42).perm().write(|w| w.set_secattr(false)); |
| 154 | 151 | ||
| 155 | let mut alloc = Allocator { | 152 | let mut alloc = Allocator { |
| 156 | start: shmem_ptr, | 153 | start: shmem_ptr, |
| @@ -158,8 +155,8 @@ async fn new_internal<'a>( | |||
| 158 | _phantom: PhantomData, | 155 | _phantom: PhantomData, |
| 159 | }; | 156 | }; |
| 160 | 157 | ||
| 161 | let ipc = unsafe { &*pac::IPC_NS::ptr() }; | 158 | let ipc = pac::IPC_NS; |
| 162 | let power = unsafe { &*pac::POWER_S::ptr() }; | 159 | let power = pac::POWER_S; |
| 163 | 160 | ||
| 164 | let cb: &mut ControlBlock = alloc.alloc().write(unsafe { mem::zeroed() }); | 161 | let cb: &mut ControlBlock = alloc.alloc().write(unsafe { mem::zeroed() }); |
| 165 | let rx = alloc.alloc_bytes(RX_SIZE); | 162 | let rx = alloc.alloc_bytes(RX_SIZE); |
| @@ -177,20 +174,20 @@ async fn new_internal<'a>( | |||
| 177 | cb.trace.base = trace.as_mut_ptr() as _; | 174 | cb.trace.base = trace.as_mut_ptr() as _; |
| 178 | cb.trace.size = TRACE_SIZE; | 175 | cb.trace.size = TRACE_SIZE; |
| 179 | 176 | ||
| 180 | ipc.gpmem[0].write(|w| unsafe { w.bits(cb as *mut _ as u32) }); | 177 | ipc.gpmem(0).write_value(cb as *mut _ as u32); |
| 181 | ipc.gpmem[1].write(|w| unsafe { w.bits(0) }); | 178 | ipc.gpmem(1).write_value(0); |
| 182 | 179 | ||
| 183 | // connect task/event i to channel i | 180 | // connect task/event i to channel i |
| 184 | for i in 0..8 { | 181 | for i in 0..8 { |
| 185 | ipc.send_cnf[i].write(|w| unsafe { w.bits(1 << i) }); | 182 | ipc.send_cnf(i).write(|w| w.0 = 1 << i); |
| 186 | ipc.receive_cnf[i].write(|w| unsafe { w.bits(1 << i) }); | 183 | ipc.receive_cnf(i).write(|w| w.0 = 1 << i); |
| 187 | } | 184 | } |
| 188 | 185 | ||
| 189 | compiler_fence(Ordering::SeqCst); | 186 | compiler_fence(Ordering::SeqCst); |
| 190 | 187 | ||
| 191 | // POWER.LTEMODEM.STARTN = 0 | 188 | // POWER.LTEMODEM.STARTN = 0 |
| 192 | // The reg is missing in the PAC?? | 189 | // The reg is missing in the PAC?? |
| 193 | let startn = unsafe { (power as *const _ as *mut u32).add(0x610 / 4) }; | 190 | let startn = unsafe { (power.as_ptr() as *mut u32).add(0x610 / 4) }; |
| 194 | unsafe { startn.write_volatile(0) } | 191 | unsafe { startn.write_volatile(0) } |
| 195 | 192 | ||
| 196 | unsafe { NVIC::unmask(pac::Interrupt::IPC) }; | 193 | unsafe { NVIC::unmask(pac::Interrupt::IPC) }; |
| @@ -322,15 +319,15 @@ struct StateInner { | |||
| 322 | impl StateInner { | 319 | impl StateInner { |
| 323 | fn poll(&mut self, trace_writer: &mut Option<TraceWriter<'_>>, ch: &mut ch::Runner<MTU>) { | 320 | fn poll(&mut self, trace_writer: &mut Option<TraceWriter<'_>>, ch: &mut ch::Runner<MTU>) { |
| 324 | trace!("poll!"); | 321 | trace!("poll!"); |
| 325 | let ipc = unsafe { &*pac::IPC_NS::ptr() }; | 322 | let ipc = pac::IPC_NS; |
| 326 | 323 | ||
| 327 | if ipc.events_receive[0].read().bits() != 0 { | 324 | if ipc.events_receive(0).read() != 0 { |
| 328 | ipc.events_receive[0].reset(); | 325 | ipc.events_receive(0).write_value(0); |
| 329 | trace!("ipc 0"); | 326 | trace!("ipc 0"); |
| 330 | } | 327 | } |
| 331 | 328 | ||
| 332 | if ipc.events_receive[2].read().bits() != 0 { | 329 | if ipc.events_receive(2).read() != 0 { |
| 333 | ipc.events_receive[2].reset(); | 330 | ipc.events_receive(2).write_value(0); |
| 334 | trace!("ipc 2"); | 331 | trace!("ipc 2"); |
| 335 | 332 | ||
| 336 | if !self.init { | 333 | if !self.init { |
| @@ -353,8 +350,8 @@ impl StateInner { | |||
| 353 | } | 350 | } |
| 354 | } | 351 | } |
| 355 | 352 | ||
| 356 | if ipc.events_receive[4].read().bits() != 0 { | 353 | if ipc.events_receive(4).read() != 0 { |
| 357 | ipc.events_receive[4].reset(); | 354 | ipc.events_receive(4).write_value(0); |
| 358 | trace!("ipc 4"); | 355 | trace!("ipc 4"); |
| 359 | 356 | ||
| 360 | loop { | 357 | loop { |
| @@ -368,13 +365,13 @@ impl StateInner { | |||
| 368 | } | 365 | } |
| 369 | } | 366 | } |
| 370 | 367 | ||
| 371 | if ipc.events_receive[6].read().bits() != 0 { | 368 | if ipc.events_receive(6).read() != 0 { |
| 372 | ipc.events_receive[6].reset(); | 369 | ipc.events_receive(6).write_value(0); |
| 373 | trace!("ipc 6"); | 370 | trace!("ipc 6"); |
| 374 | } | 371 | } |
| 375 | 372 | ||
| 376 | if ipc.events_receive[7].read().bits() != 0 { | 373 | if ipc.events_receive(7).read() != 0 { |
| 377 | ipc.events_receive[7].reset(); | 374 | ipc.events_receive(7).write_value(0); |
| 378 | trace!("ipc 7: trace"); | 375 | trace!("ipc 7: trace"); |
| 379 | 376 | ||
| 380 | let msg = unsafe { addr_of!((*self.cb).trace.rx_state).read_volatile() }; | 377 | let msg = unsafe { addr_of!((*self.cb).trace.rx_state).read_volatile() }; |
| @@ -437,13 +434,12 @@ impl StateInner { | |||
| 437 | } | 434 | } |
| 438 | } | 435 | } |
| 439 | 436 | ||
| 440 | ipc.intenset.write(|w| { | 437 | ipc.intenset().write(|w| { |
| 441 | w.receive0().set_bit(); | 438 | w.set_receive0(true); |
| 442 | w.receive2().set_bit(); | 439 | w.set_receive2(true); |
| 443 | w.receive4().set_bit(); | 440 | w.set_receive4(true); |
| 444 | w.receive6().set_bit(); | 441 | w.set_receive6(true); |
| 445 | w.receive7().set_bit(); | 442 | w.set_receive7(true); |
| 446 | w | ||
| 447 | }); | 443 | }); |
| 448 | } | 444 | } |
| 449 | 445 | ||
| @@ -546,8 +542,8 @@ impl StateInner { | |||
| 546 | unsafe { addr_of_mut!((*list_item).state).write_volatile((self.tx_seq_no as u32) << 16 | 0x01) } | 542 | unsafe { addr_of_mut!((*list_item).state).write_volatile((self.tx_seq_no as u32) << 16 | 0x01) } |
| 547 | self.tx_seq_no = self.tx_seq_no.wrapping_add(1); | 543 | self.tx_seq_no = self.tx_seq_no.wrapping_add(1); |
| 548 | 544 | ||
| 549 | let ipc = unsafe { &*pac::IPC_NS::ptr() }; | 545 | let ipc = pac::IPC_NS; |
| 550 | ipc.tasks_send[ipc_ch].write(|w| unsafe { w.bits(1) }); | 546 | ipc.tasks_send(ipc_ch).write_value(1); |
| 551 | Ok(()) | 547 | Ok(()) |
| 552 | } | 548 | } |
| 553 | 549 | ||
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 3e66d6886..90fa7a16c 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -15,7 +15,7 @@ src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-nrf/s | |||
| 15 | 15 | ||
| 16 | features = ["time", "defmt", "unstable-pac", "gpiote", "time-driver-rtc1"] | 16 | features = ["time", "defmt", "unstable-pac", "gpiote", "time-driver-rtc1"] |
| 17 | flavors = [ | 17 | flavors = [ |
| 18 | { regex_feature = "nrf51", target = "thumbv6m-none-eabi" }, | 18 | { regex_feature = "_nrf51", target = "thumbv6m-none-eabi" }, |
| 19 | { regex_feature = "nrf52.*", target = "thumbv7em-none-eabihf" }, | 19 | { regex_feature = "nrf52.*", target = "thumbv7em-none-eabihf" }, |
| 20 | { regex_feature = "nrf53.*", target = "thumbv8m.main-none-eabihf" }, | 20 | { regex_feature = "nrf53.*", target = "thumbv8m.main-none-eabihf" }, |
| 21 | { regex_feature = "nrf91.*", target = "thumbv8m.main-none-eabihf" }, | 21 | { regex_feature = "nrf91.*", target = "thumbv8m.main-none-eabihf" }, |
| @@ -28,20 +28,7 @@ rustdoc-args = ["--cfg", "docsrs"] | |||
| 28 | [features] | 28 | [features] |
| 29 | default = ["rt"] | 29 | default = ["rt"] |
| 30 | ## Cortex-M runtime (enabled by default) | 30 | ## Cortex-M runtime (enabled by default) |
| 31 | rt = [ | 31 | rt = ["nrf-pac/rt"] |
| 32 | "nrf51-pac?/rt", | ||
| 33 | "nrf52805-pac?/rt", | ||
| 34 | "nrf52810-pac?/rt", | ||
| 35 | "nrf52811-pac?/rt", | ||
| 36 | "nrf52820-pac?/rt", | ||
| 37 | "nrf52832-pac?/rt", | ||
| 38 | "nrf52833-pac?/rt", | ||
| 39 | "nrf52840-pac?/rt", | ||
| 40 | "nrf5340-app-pac?/rt", | ||
| 41 | "nrf5340-net-pac?/rt", | ||
| 42 | "nrf9160-pac?/rt", | ||
| 43 | "nrf9120-pac?/rt", | ||
| 44 | ] | ||
| 45 | 32 | ||
| 46 | ## Enable features requiring `embassy-time` | 33 | ## Enable features requiring `embassy-time` |
| 47 | time = ["dep:embassy-time"] | 34 | time = ["dep:embassy-time"] |
| @@ -75,21 +62,21 @@ qspi-multiwrite-flash = [] | |||
| 75 | 62 | ||
| 76 | #! ### Chip selection features | 63 | #! ### Chip selection features |
| 77 | ## nRF51 | 64 | ## nRF51 |
| 78 | nrf51 = ["nrf51-pac", "_nrf51"] | 65 | nrf51 = ["nrf-pac/nrf51", "_nrf51"] |
| 79 | ## nRF52805 | 66 | ## nRF52805 |
| 80 | nrf52805 = ["nrf52805-pac", "_nrf52"] | 67 | nrf52805 = ["nrf-pac/nrf52805", "_nrf52"] |
| 81 | ## nRF52810 | 68 | ## nRF52810 |
| 82 | nrf52810 = ["nrf52810-pac", "_nrf52"] | 69 | nrf52810 = ["nrf-pac/nrf52810", "_nrf52"] |
| 83 | ## nRF52811 | 70 | ## nRF52811 |
| 84 | nrf52811 = ["nrf52811-pac", "_nrf52"] | 71 | nrf52811 = ["nrf-pac/nrf52811", "_nrf52"] |
| 85 | ## nRF52820 | 72 | ## nRF52820 |
| 86 | nrf52820 = ["nrf52820-pac", "_nrf52"] | 73 | nrf52820 = ["nrf-pac/nrf52820", "_nrf52"] |
| 87 | ## nRF52832 | 74 | ## nRF52832 |
| 88 | nrf52832 = ["nrf52832-pac", "_nrf52", "_nrf52832_anomaly_109"] | 75 | nrf52832 = ["nrf-pac/nrf52832", "_nrf52", "_nrf52832_anomaly_109"] |
| 89 | ## nRF52833 | 76 | ## nRF52833 |
| 90 | nrf52833 = ["nrf52833-pac", "_nrf52", "_gpio-p1"] | 77 | nrf52833 = ["nrf-pac/nrf52833", "_nrf52", "_gpio-p1"] |
| 91 | ## nRF52840 | 78 | ## nRF52840 |
| 92 | nrf52840 = ["nrf52840-pac", "_nrf52", "_gpio-p1"] | 79 | nrf52840 = ["nrf-pac/nrf52840", "_nrf52", "_gpio-p1"] |
| 93 | ## nRF5340 application core in Secure mode | 80 | ## nRF5340 application core in Secure mode |
| 94 | nrf5340-app-s = ["_nrf5340-app", "_s"] | 81 | nrf5340-app-s = ["_nrf5340-app", "_s"] |
| 95 | ## nRF5340 application core in Non-Secure mode | 82 | ## nRF5340 application core in Non-Secure mode |
| @@ -113,11 +100,11 @@ nrf9161-ns = ["nrf9120-ns"] | |||
| 113 | # Features starting with `_` are for internal use only. They're not intended | 100 | # Features starting with `_` are for internal use only. They're not intended |
| 114 | # to be enabled by other crates, and are not covered by semver guarantees. | 101 | # to be enabled by other crates, and are not covered by semver guarantees. |
| 115 | 102 | ||
| 116 | _nrf5340-app = ["_nrf5340", "nrf5340-app-pac"] | 103 | _nrf5340-app = ["_nrf5340", "nrf-pac/nrf5340-app"] |
| 117 | _nrf5340-net = ["_nrf5340", "nrf5340-net-pac"] | 104 | _nrf5340-net = ["_nrf5340", "nrf-pac/nrf5340-net"] |
| 118 | _nrf5340 = ["_gpio-p1", "_dppi"] | 105 | _nrf5340 = ["_gpio-p1", "_dppi"] |
| 119 | _nrf9160 = ["nrf9160-pac", "_dppi"] | 106 | _nrf9160 = ["nrf-pac/nrf9160", "_dppi"] |
| 120 | _nrf9120 = ["nrf9120-pac", "_dppi"] | 107 | _nrf9120 = ["nrf-pac/nrf9120", "_dppi"] |
| 121 | _nrf52 = ["_ppi"] | 108 | _nrf52 = ["_ppi"] |
| 122 | _nrf51 = ["_ppi"] | 109 | _nrf51 = ["_ppi"] |
| 123 | _nrf91 = [] | 110 | _nrf91 = [] |
| @@ -149,6 +136,8 @@ embedded-hal-async = { version = "1.0" } | |||
| 149 | embedded-io = { version = "0.6.0" } | 136 | embedded-io = { version = "0.6.0" } |
| 150 | embedded-io-async = { version = "0.6.1" } | 137 | embedded-io-async = { version = "0.6.1" } |
| 151 | 138 | ||
| 139 | nrf-pac = { git = "https://github.com/embassy-rs/nrf-pac", rev = "875a29629cc1c87aae00cfea647a956b3807d8be" } | ||
| 140 | |||
| 152 | defmt = { version = "0.3", optional = true } | 141 | defmt = { version = "0.3", optional = true } |
| 153 | bitflags = "2.4.2" | 142 | bitflags = "2.4.2" |
| 154 | log = { version = "0.4.14", optional = true } | 143 | log = { version = "0.4.14", optional = true } |
| @@ -162,15 +151,3 @@ embedded-storage-async = "0.4.1" | |||
| 162 | cfg-if = "1.0.0" | 151 | cfg-if = "1.0.0" |
| 163 | document-features = "0.2.7" | 152 | document-features = "0.2.7" |
| 164 | 153 | ||
| 165 | nrf51-pac = { version = "0.12.0", optional = true } | ||
| 166 | nrf52805-pac = { version = "0.12.0", optional = true } | ||
| 167 | nrf52810-pac = { version = "0.12.0", optional = true } | ||
| 168 | nrf52811-pac = { version = "0.12.0", optional = true } | ||
| 169 | nrf52820-pac = { version = "0.12.0", optional = true } | ||
| 170 | nrf52832-pac = { version = "0.12.0", optional = true } | ||
| 171 | nrf52833-pac = { version = "0.12.0", optional = true } | ||
| 172 | nrf52840-pac = { version = "0.12.0", optional = true } | ||
| 173 | nrf5340-app-pac = { version = "0.12.0", optional = true } | ||
| 174 | nrf5340-net-pac = { version = "0.12.0", optional = true } | ||
| 175 | nrf9160-pac = { version = "0.12.0", optional = true } | ||
| 176 | nrf9120-pac = { version = "0.12.0", optional = true } | ||
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 6d39597c6..b55e70a36 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -17,16 +17,17 @@ use core::task::Poll; | |||
| 17 | 17 | ||
| 18 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | 18 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; |
| 19 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 19 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 20 | use pac::uarte::vals; | ||
| 20 | // Re-export SVD variants to allow user to directly set values | 21 | // Re-export SVD variants to allow user to directly set values |
| 21 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 22 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; |
| 22 | 23 | ||
| 23 | use crate::gpio::{AnyPin, Pin as GpioPin, PselBits, SealedPin}; | 24 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 24 | use crate::interrupt::typelevel::Interrupt; | 25 | use crate::interrupt::typelevel::Interrupt; |
| 25 | use crate::ppi::{ | 26 | use crate::ppi::{ |
| 26 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, | 27 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, |
| 27 | }; | 28 | }; |
| 28 | use crate::timer::{Instance as TimerInstance, Timer}; | 29 | use crate::timer::{Instance as TimerInstance, Timer}; |
| 29 | use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance}; | 30 | use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance}; |
| 30 | use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; | 31 | use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; |
| 31 | 32 | ||
| 32 | pub(crate) struct State { | 33 | pub(crate) struct State { |
| @@ -79,57 +80,57 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 79 | let buf_len = s.rx_buf.len(); | 80 | let buf_len = s.rx_buf.len(); |
| 80 | let half_len = buf_len / 2; | 81 | let half_len = buf_len / 2; |
| 81 | 82 | ||
| 82 | if r.events_error.read().bits() != 0 { | 83 | if r.events_error().read() != 0 { |
| 83 | r.events_error.reset(); | 84 | r.events_error().write_value(0); |
| 84 | let errs = r.errorsrc.read(); | 85 | let errs = r.errorsrc().read(); |
| 85 | r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) }); | 86 | r.errorsrc().write_value(errs); |
| 86 | 87 | ||
| 87 | if errs.overrun().bit() { | 88 | if errs.overrun() { |
| 88 | panic!("BufferedUarte overrun"); | 89 | panic!("BufferedUarte overrun"); |
| 89 | } | 90 | } |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 92 | // Received some bytes, wake task. | 93 | // Received some bytes, wake task. |
| 93 | if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 { | 94 | if r.inten().read().rxdrdy() && r.events_rxdrdy().read() != 0 { |
| 94 | r.intenclr.write(|w| w.rxdrdy().clear()); | 95 | r.intenclr().write(|w| w.set_rxdrdy(true)); |
| 95 | r.events_rxdrdy.reset(); | 96 | r.events_rxdrdy().write_value(0); |
| 96 | ss.rx_waker.wake(); | 97 | ss.rx_waker.wake(); |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 99 | if r.events_endrx.read().bits() != 0 { | 100 | if r.events_endrx().read() != 0 { |
| 100 | //trace!(" irq_rx: endrx"); | 101 | //trace!(" irq_rx: endrx"); |
| 101 | r.events_endrx.reset(); | 102 | r.events_endrx().write_value(0); |
| 102 | 103 | ||
| 103 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 104 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 104 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 105 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) { | 108 | if r.events_rxstarted().read() != 0 || !s.rx_started.load(Ordering::Relaxed) { |
| 108 | //trace!(" irq_rx: rxstarted"); | 109 | //trace!(" irq_rx: rxstarted"); |
| 109 | let (ptr, len) = rx.push_buf(); | 110 | let (ptr, len) = rx.push_buf(); |
| 110 | if len >= half_len { | 111 | if len >= half_len { |
| 111 | r.events_rxstarted.reset(); | 112 | r.events_rxstarted().write_value(0); |
| 112 | 113 | ||
| 113 | //trace!(" irq_rx: starting second {:?}", half_len); | 114 | //trace!(" irq_rx: starting second {:?}", half_len); |
| 114 | 115 | ||
| 115 | // Set up the DMA read | 116 | // Set up the DMA read |
| 116 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 117 | r.rxd().ptr().write_value(ptr as u32); |
| 117 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) }); | 118 | r.rxd().maxcnt().write(|w| w.set_maxcnt(half_len as _)); |
| 118 | 119 | ||
| 119 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); | 120 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); |
| 120 | 121 | ||
| 121 | // Enable endrx -> startrx PPI channel. | 122 | // Enable endrx -> startrx PPI channel. |
| 122 | // From this point on, if endrx happens, startrx is automatically fired. | 123 | // From this point on, if endrx happens, startrx is automatically fired. |
| 123 | ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) }); | 124 | ppi::regs().chenset().write(|w| w.0 = 1 << chn); |
| 124 | 125 | ||
| 125 | // It is possible that endrx happened BEFORE enabling the PPI. In this case | 126 | // It is possible that endrx happened BEFORE enabling the PPI. In this case |
| 126 | // the PPI channel doesn't trigger, and we'd hang. We have to detect this | 127 | // the PPI channel doesn't trigger, and we'd hang. We have to detect this |
| 127 | // and manually start. | 128 | // and manually start. |
| 128 | 129 | ||
| 129 | // check again in case endrx has happened between the last check and now. | 130 | // check again in case endrx has happened between the last check and now. |
| 130 | if r.events_endrx.read().bits() != 0 { | 131 | if r.events_endrx().read() != 0 { |
| 131 | //trace!(" irq_rx: endrx"); | 132 | //trace!(" irq_rx: endrx"); |
| 132 | r.events_endrx.reset(); | 133 | r.events_endrx().write_value(0); |
| 133 | 134 | ||
| 134 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 135 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 135 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 136 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| @@ -144,7 +145,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 144 | 145 | ||
| 145 | // Check if the PPI channel is still enabled. The PPI channel disables itself | 146 | // Check if the PPI channel is still enabled. The PPI channel disables itself |
| 146 | // when it fires, so if it's still enabled it hasn't fired. | 147 | // when it fires, so if it's still enabled it hasn't fired. |
| 147 | let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0; | 148 | let ppi_ch_enabled = ppi::regs().chen().read().ch(chn as _); |
| 148 | 149 | ||
| 149 | // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. | 150 | // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. |
| 150 | // this condition also naturally matches if `!started`, needed to kickstart the DMA. | 151 | // this condition also naturally matches if `!started`, needed to kickstart the DMA. |
| @@ -152,10 +153,10 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 152 | //trace!("manually starting."); | 153 | //trace!("manually starting."); |
| 153 | 154 | ||
| 154 | // disable the ppi ch, it's of no use anymore. | 155 | // disable the ppi ch, it's of no use anymore. |
| 155 | ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) }); | 156 | ppi::regs().chenclr().write(|w| w.set_ch(chn as _, true)); |
| 156 | 157 | ||
| 157 | // manually start | 158 | // manually start |
| 158 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 159 | r.tasks_startrx().write_value(1); |
| 159 | } | 160 | } |
| 160 | 161 | ||
| 161 | rx.push_done(half_len); | 162 | rx.push_done(half_len); |
| @@ -164,7 +165,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 164 | s.rx_started.store(true, Ordering::Relaxed); | 165 | s.rx_started.store(true, Ordering::Relaxed); |
| 165 | } else { | 166 | } else { |
| 166 | //trace!(" irq_rx: rxstarted no buf"); | 167 | //trace!(" irq_rx: rxstarted no buf"); |
| 167 | r.intenclr.write(|w| w.rxstarted().clear()); | 168 | r.intenclr().write(|w| w.set_rxstarted(true)); |
| 168 | } | 169 | } |
| 169 | } | 170 | } |
| 170 | } | 171 | } |
| @@ -173,8 +174,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 173 | 174 | ||
| 174 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { | 175 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { |
| 175 | // TX end | 176 | // TX end |
| 176 | if r.events_endtx.read().bits() != 0 { | 177 | if r.events_endtx().read() != 0 { |
| 177 | r.events_endtx.reset(); | 178 | r.events_endtx().write_value(0); |
| 178 | 179 | ||
| 179 | let n = s.tx_count.load(Ordering::Relaxed); | 180 | let n = s.tx_count.load(Ordering::Relaxed); |
| 180 | //trace!(" irq_tx: endtx {:?}", n); | 181 | //trace!(" irq_tx: endtx {:?}", n); |
| @@ -192,11 +193,11 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 192 | s.tx_count.store(len, Ordering::Relaxed); | 193 | s.tx_count.store(len, Ordering::Relaxed); |
| 193 | 194 | ||
| 194 | // Set up the DMA write | 195 | // Set up the DMA write |
| 195 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 196 | r.txd().ptr().write_value(ptr as u32); |
| 196 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 197 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 197 | 198 | ||
| 198 | // Start UARTE Transmit transaction | 199 | // Start UARTE Transmit transaction |
| 199 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 200 | r.tasks_starttx().write_value(1); |
| 200 | } | 201 | } |
| 201 | } | 202 | } |
| 202 | } | 203 | } |
| @@ -308,7 +309,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 308 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); | 309 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); |
| 309 | let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); | 310 | let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); |
| 310 | 311 | ||
| 311 | U::regs().enable.write(|w| w.enable().enabled()); | 312 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 312 | U::Interrupt::pend(); | 313 | U::Interrupt::pend(); |
| 313 | unsafe { U::Interrupt::enable() }; | 314 | unsafe { U::Interrupt::enable() }; |
| 314 | 315 | ||
| @@ -320,7 +321,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 320 | /// Adjust the baud rate to the provided value. | 321 | /// Adjust the baud rate to the provided value. |
| 321 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | 322 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { |
| 322 | let r = U::regs(); | 323 | let r = U::regs(); |
| 323 | r.baudrate.write(|w| w.baudrate().variant(baudrate)); | 324 | r.baudrate().write(|w| w.set_baudrate(baudrate)); |
| 324 | } | 325 | } |
| 325 | 326 | ||
| 326 | /// Split the UART in reader and writer parts. | 327 | /// Split the UART in reader and writer parts. |
| @@ -415,7 +416,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 415 | 416 | ||
| 416 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); | 417 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); |
| 417 | 418 | ||
| 418 | U::regs().enable.write(|w| w.enable().enabled()); | 419 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 419 | U::Interrupt::pend(); | 420 | U::Interrupt::pend(); |
| 420 | unsafe { U::Interrupt::enable() }; | 421 | unsafe { U::Interrupt::enable() }; |
| 421 | 422 | ||
| @@ -432,14 +433,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 432 | ) -> Self { | 433 | ) -> Self { |
| 433 | let r = U::regs(); | 434 | let r = U::regs(); |
| 434 | 435 | ||
| 435 | txd.set_high(); | 436 | configure_tx_pins(r, txd, cts); |
| 436 | txd.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 437 | r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); | ||
| 438 | |||
| 439 | if let Some(pin) = &cts { | ||
| 440 | pin.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 441 | } | ||
| 442 | r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); | ||
| 443 | 437 | ||
| 444 | // Initialize state | 438 | // Initialize state |
| 445 | let s = U::buffered_state(); | 439 | let s = U::buffered_state(); |
| @@ -447,12 +441,11 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 447 | let len = tx_buffer.len(); | 441 | let len = tx_buffer.len(); |
| 448 | unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | 442 | unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; |
| 449 | 443 | ||
| 450 | r.events_txstarted.reset(); | 444 | r.events_txstarted().write_value(0); |
| 451 | 445 | ||
| 452 | // Enable interrupts | 446 | // Enable interrupts |
| 453 | r.intenset.write(|w| { | 447 | r.intenset().write(|w| { |
| 454 | w.endtx().set(); | 448 | w.set_endtx(true); |
| 455 | w | ||
| 456 | }); | 449 | }); |
| 457 | 450 | ||
| 458 | Self { _peri: peri } | 451 | Self { _peri: peri } |
| @@ -532,15 +525,14 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { | |||
| 532 | fn drop(&mut self) { | 525 | fn drop(&mut self) { |
| 533 | let r = U::regs(); | 526 | let r = U::regs(); |
| 534 | 527 | ||
| 535 | r.intenclr.write(|w| { | 528 | r.intenclr().write(|w| { |
| 536 | w.txdrdy().set_bit(); | 529 | w.set_txdrdy(true); |
| 537 | w.txstarted().set_bit(); | 530 | w.set_txstarted(true); |
| 538 | w.txstopped().set_bit(); | 531 | w.set_txstopped(true); |
| 539 | w | ||
| 540 | }); | 532 | }); |
| 541 | r.events_txstopped.reset(); | 533 | r.events_txstopped().write_value(0); |
| 542 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | 534 | r.tasks_stoptx().write_value(1); |
| 543 | while r.events_txstopped.read().bits() == 0 {} | 535 | while r.events_txstopped().read() == 0 {} |
| 544 | 536 | ||
| 545 | let s = U::buffered_state(); | 537 | let s = U::buffered_state(); |
| 546 | unsafe { s.tx_buf.deinit() } | 538 | unsafe { s.tx_buf.deinit() } |
| @@ -639,7 +631,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 639 | 631 | ||
| 640 | let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); | 632 | let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); |
| 641 | 633 | ||
| 642 | U::regs().enable.write(|w| w.enable().enabled()); | 634 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 643 | U::Interrupt::pend(); | 635 | U::Interrupt::pend(); |
| 644 | unsafe { U::Interrupt::enable() }; | 636 | unsafe { U::Interrupt::enable() }; |
| 645 | 637 | ||
| @@ -663,14 +655,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 663 | 655 | ||
| 664 | let r = U::regs(); | 656 | let r = U::regs(); |
| 665 | 657 | ||
| 666 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); | 658 | configure_rx_pins(r, rxd, rts); |
| 667 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | ||
| 668 | |||
| 669 | if let Some(pin) = &rts { | ||
| 670 | pin.set_high(); | ||
| 671 | pin.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 672 | } | ||
| 673 | r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); | ||
| 674 | 659 | ||
| 675 | // Initialize state | 660 | // Initialize state |
| 676 | let s = U::buffered_state(); | 661 | let s = U::buffered_state(); |
| @@ -681,20 +666,19 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 681 | unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; | 666 | unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; |
| 682 | 667 | ||
| 683 | // clear errors | 668 | // clear errors |
| 684 | let errors = r.errorsrc.read().bits(); | 669 | let errors = r.errorsrc().read(); |
| 685 | r.errorsrc.write(|w| unsafe { w.bits(errors) }); | 670 | r.errorsrc().write_value(errors); |
| 686 | 671 | ||
| 687 | r.events_rxstarted.reset(); | 672 | r.events_rxstarted().write_value(0); |
| 688 | r.events_error.reset(); | 673 | r.events_error().write_value(0); |
| 689 | r.events_endrx.reset(); | 674 | r.events_endrx().write_value(0); |
| 690 | 675 | ||
| 691 | // Enable interrupts | 676 | // Enable interrupts |
| 692 | r.intenset.write(|w| { | 677 | r.intenset().write(|w| { |
| 693 | w.endtx().set(); | 678 | w.set_endtx(true); |
| 694 | w.rxstarted().set(); | 679 | w.set_rxstarted(true); |
| 695 | w.error().set(); | 680 | w.set_error(true); |
| 696 | w.endrx().set(); | 681 | w.set_endrx(true); |
| 697 | w | ||
| 698 | }); | 682 | }); |
| 699 | 683 | ||
| 700 | // Configure byte counter. | 684 | // Configure byte counter. |
| @@ -704,15 +688,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 704 | timer.clear(); | 688 | timer.clear(); |
| 705 | timer.start(); | 689 | timer.start(); |
| 706 | 690 | ||
| 707 | let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(&r.events_rxdrdy), timer.task_count()); | 691 | let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(r.events_rxdrdy()), timer.task_count()); |
| 708 | ppi_ch1.enable(); | 692 | ppi_ch1.enable(); |
| 709 | 693 | ||
| 710 | s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed); | 694 | s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed); |
| 711 | let mut ppi_group = PpiGroup::new(ppi_group); | 695 | let mut ppi_group = PpiGroup::new(ppi_group); |
| 712 | let mut ppi_ch2 = Ppi::new_one_to_two( | 696 | let mut ppi_ch2 = Ppi::new_one_to_two( |
| 713 | ppi_ch2, | 697 | ppi_ch2, |
| 714 | Event::from_reg(&r.events_endrx), | 698 | Event::from_reg(r.events_endrx()), |
| 715 | Task::from_reg(&r.tasks_startrx), | 699 | Task::from_reg(r.tasks_startrx()), |
| 716 | ppi_group.task_disable_all(), | 700 | ppi_group.task_disable_all(), |
| 717 | ); | 701 | ); |
| 718 | ppi_ch2.disable(); | 702 | ppi_ch2.disable(); |
| @@ -747,8 +731,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 747 | let ss = U::state(); | 731 | let ss = U::state(); |
| 748 | 732 | ||
| 749 | // Read the RXDRDY counter. | 733 | // Read the RXDRDY counter. |
| 750 | T::regs().tasks_capture[0].write(|w| unsafe { w.bits(1) }); | 734 | T::regs().tasks_capture(0).write_value(1); |
| 751 | let mut end = T::regs().cc[0].read().bits() as usize; | 735 | let mut end = T::regs().cc(0).read() as usize; |
| 752 | //trace!(" rxdrdy count = {:?}", end); | 736 | //trace!(" rxdrdy count = {:?}", end); |
| 753 | 737 | ||
| 754 | // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. | 738 | // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. |
| @@ -769,7 +753,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 769 | if start == end { | 753 | if start == end { |
| 770 | //trace!(" empty"); | 754 | //trace!(" empty"); |
| 771 | ss.rx_waker.register(cx.waker()); | 755 | ss.rx_waker.register(cx.waker()); |
| 772 | r.intenset.write(|w| w.rxdrdy().set_bit()); | 756 | r.intenset().write(|w| w.set_rxdrdy(true)); |
| 773 | return Poll::Pending; | 757 | return Poll::Pending; |
| 774 | } | 758 | } |
| 775 | 759 | ||
| @@ -799,7 +783,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 799 | let s = U::buffered_state(); | 783 | let s = U::buffered_state(); |
| 800 | let mut rx = unsafe { s.rx_buf.reader() }; | 784 | let mut rx = unsafe { s.rx_buf.reader() }; |
| 801 | rx.pop_done(amt); | 785 | rx.pop_done(amt); |
| 802 | U::regs().intenset.write(|w| w.rxstarted().set()); | 786 | U::regs().intenset().write(|w| w.set_rxstarted(true)); |
| 803 | } | 787 | } |
| 804 | 788 | ||
| 805 | /// we are ready to read if there is data in the buffer | 789 | /// we are ready to read if there is data in the buffer |
| @@ -817,15 +801,14 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarteRx<'a, U, T> | |||
| 817 | 801 | ||
| 818 | self.timer.stop(); | 802 | self.timer.stop(); |
| 819 | 803 | ||
| 820 | r.intenclr.write(|w| { | 804 | r.intenclr().write(|w| { |
| 821 | w.rxdrdy().set_bit(); | 805 | w.set_rxdrdy(true); |
| 822 | w.rxstarted().set_bit(); | 806 | w.set_rxstarted(true); |
| 823 | w.rxto().set_bit(); | 807 | w.set_rxto(true); |
| 824 | w | ||
| 825 | }); | 808 | }); |
| 826 | r.events_rxto.reset(); | 809 | r.events_rxto().write_value(0); |
| 827 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | 810 | r.tasks_stoprx().write_value(1); |
| 828 | while r.events_rxto.read().bits() == 0 {} | 811 | while r.events_rxto().read() == 0 {} |
| 829 | 812 | ||
| 830 | let s = U::buffered_state(); | 813 | let s = U::buffered_state(); |
| 831 | unsafe { s.rx_buf.deinit() } | 814 | unsafe { s.rx_buf.deinit() } |
diff --git a/embassy-nrf/src/chips/nrf51.rs b/embassy-nrf/src/chips/nrf51.rs index cc1cbc8a0..95fa926c3 100644 --- a/embassy-nrf/src/chips/nrf51.rs +++ b/embassy-nrf/src/chips/nrf51.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf51_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index b51b0c93e..fc8db856c 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52805_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 273098d9b..11a8b4dde 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52810_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 10) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 10) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 9bce38636..077a36e31 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52811_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 14) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 2acae2c8f..6ee16706d 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52820_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 15) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 15) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 94b373ab3..4a7a29229 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52832_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 8) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 8) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 09cde1ac1..6d70b763f 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52833_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; |
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 0f3d1b250..b6afbf213 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | pub use nrf52840_pac as pac; | 1 | pub use nrf_pac as pac; |
| 2 | 2 | ||
| 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 3 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 4 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; | 4 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; |
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index 584f6e43c..43588eef3 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs | |||
| @@ -5,16 +5,17 @@ pub mod pac { | |||
| 5 | // The nRF5340 has a secure and non-secure (NS) mode. | 5 | // The nRF5340 has a secure and non-secure (NS) mode. |
| 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. | 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. |
| 7 | 7 | ||
| 8 | pub use nrf5340_app_pac::NVIC_PRIO_BITS; | 8 | #[cfg(feature="rt")] |
| 9 | pub use nrf_pac::NVIC_PRIO_BITS; | ||
| 10 | pub use nrf_pac::{common, shared}; | ||
| 9 | 11 | ||
| 10 | #[cfg(feature="rt")] | 12 | #[cfg(feature="rt")] |
| 11 | #[doc(no_inline)] | 13 | #[doc(no_inline)] |
| 12 | pub use nrf5340_app_pac::interrupt; | 14 | pub use nrf_pac::interrupt; |
| 13 | 15 | ||
| 14 | #[doc(no_inline)] | 16 | #[doc(no_inline)] |
| 15 | pub use nrf5340_app_pac::{ | 17 | pub use nrf_pac::{ |
| 16 | Interrupt, | 18 | Interrupt, |
| 17 | Peripherals, | ||
| 18 | 19 | ||
| 19 | cache_s as cache, | 20 | cache_s as cache, |
| 20 | cachedata_s as cachedata, | 21 | cachedata_s as cachedata, |
| @@ -26,11 +27,11 @@ pub mod pac { | |||
| 26 | ctrlap_ns as ctrlap, | 27 | ctrlap_ns as ctrlap, |
| 27 | dcnf_ns as dcnf, | 28 | dcnf_ns as dcnf, |
| 28 | dppic_ns as dppic, | 29 | dppic_ns as dppic, |
| 29 | egu0_ns as egu0, | 30 | egu_ns as egu, |
| 30 | ficr_s as ficr, | 31 | ficr_s as ficr, |
| 31 | fpu_ns as fpu, | 32 | fpu_ns as fpu, |
| 32 | gpiote0_s as gpiote, | 33 | gpiote_s as gpiote, |
| 33 | i2s0_ns as i2s0, | 34 | i2s_ns as i2s, |
| 34 | ipc_ns as ipc, | 35 | ipc_ns as ipc, |
| 35 | kmu_ns as kmu, | 36 | kmu_ns as kmu, |
| 36 | lpcomp_ns as lpcomp, | 37 | lpcomp_ns as lpcomp, |
| @@ -38,36 +39,36 @@ pub mod pac { | |||
| 38 | nfct_ns as nfct, | 39 | nfct_ns as nfct, |
| 39 | nvmc_ns as nvmc, | 40 | nvmc_ns as nvmc, |
| 40 | oscillators_ns as oscillators, | 41 | oscillators_ns as oscillators, |
| 41 | p0_ns as p0, | 42 | gpio_ns as gpio, |
| 42 | pdm0_ns as pdm, | 43 | pdm_ns as pdm, |
| 43 | power_ns as power, | 44 | power_ns as power, |
| 44 | pwm0_ns as pwm0, | 45 | pwm_ns as pwm, |
| 45 | qdec0_ns as qdec, | 46 | qdec_ns as qdec, |
| 46 | qspi_ns as qspi, | 47 | qspi_ns as qspi, |
| 47 | regulators_ns as regulators, | 48 | regulators_ns as regulators, |
| 48 | reset_ns as reset, | 49 | reset_ns as reset, |
| 49 | rtc0_ns as rtc0, | 50 | rtc_ns as rtc, |
| 50 | saadc_ns as saadc, | 51 | saadc_ns as saadc, |
| 51 | spim0_ns as spim0, | 52 | spim_ns as spim, |
| 52 | spis0_ns as spis0, | 53 | spis_ns as spis, |
| 53 | spu_s as spu, | 54 | spu_s as spu, |
| 54 | tad_s as tad, | 55 | tad_s as tad, |
| 55 | timer0_ns as timer0, | 56 | timer_ns as timer, |
| 56 | twim0_ns as twim0, | 57 | twim_ns as twim, |
| 57 | twis0_ns as twis0, | 58 | twis_ns as twis, |
| 58 | uarte0_ns as uarte0, | 59 | uarte_ns as uarte, |
| 59 | uicr_s as uicr, | 60 | uicr_s as uicr, |
| 60 | usbd_ns as usbd, | 61 | usbd_ns as usbd, |
| 61 | usbregulator_ns as usbregulator, | 62 | usbregulator_ns as usbregulator, |
| 62 | vmc_ns as vmc, | 63 | vmc_ns as vmc, |
| 63 | wdt0_ns as wdt0, | 64 | wdt_ns as wdt, |
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | /// Non-Secure mode (NS) peripherals | 67 | /// Non-Secure mode (NS) peripherals |
| 67 | pub mod ns { | 68 | pub mod ns { |
| 68 | #[cfg(feature = "nrf5340-app-ns")] | 69 | #[cfg(feature = "nrf5340-app-ns")] |
| 69 | #[doc(no_inline)] | 70 | #[doc(no_inline)] |
| 70 | pub use nrf5340_app_pac::{ | 71 | pub use nrf_pac::{ |
| 71 | CLOCK_NS as CLOCK, | 72 | CLOCK_NS as CLOCK, |
| 72 | COMP_NS as COMP, | 73 | COMP_NS as COMP, |
| 73 | CTRLAP_NS as CTRLAP, | 74 | CTRLAP_NS as CTRLAP, |
| @@ -141,7 +142,7 @@ pub mod pac { | |||
| 141 | pub mod s { | 142 | pub mod s { |
| 142 | #[cfg(feature = "nrf5340-app-s")] | 143 | #[cfg(feature = "nrf5340-app-s")] |
| 143 | #[doc(no_inline)] | 144 | #[doc(no_inline)] |
| 144 | pub use nrf5340_app_pac::{ | 145 | pub use nrf_pac::{ |
| 145 | CACHEDATA_S as CACHEDATA, | 146 | CACHEDATA_S as CACHEDATA, |
| 146 | CACHEINFO_S as CACHEINFO, | 147 | CACHEINFO_S as CACHEINFO, |
| 147 | CACHE_S as CACHE, | 148 | CACHE_S as CACHE, |
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index d772c9a49..00ff5fea6 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs | |||
| @@ -5,16 +5,17 @@ pub mod pac { | |||
| 5 | // The nRF5340 has a secure and non-secure (NS) mode. | 5 | // The nRF5340 has a secure and non-secure (NS) mode. |
| 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. | 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. |
| 7 | 7 | ||
| 8 | pub use nrf5340_net_pac::NVIC_PRIO_BITS; | 8 | #[cfg(feature="rt")] |
| 9 | pub use nrf_pac::NVIC_PRIO_BITS; | ||
| 10 | pub use nrf_pac::{common, shared}; | ||
| 9 | 11 | ||
| 10 | #[cfg(feature="rt")] | 12 | #[cfg(feature="rt")] |
| 11 | #[doc(no_inline)] | 13 | #[doc(no_inline)] |
| 12 | pub use nrf5340_net_pac::interrupt; | 14 | pub use nrf_pac::interrupt; |
| 13 | 15 | ||
| 14 | #[doc(no_inline)] | 16 | #[doc(no_inline)] |
| 15 | pub use nrf5340_net_pac::{ | 17 | pub use nrf_pac::{ |
| 16 | Interrupt, | 18 | Interrupt, |
| 17 | Peripherals, | ||
| 18 | 19 | ||
| 19 | aar_ns as aar, | 20 | aar_ns as aar, |
| 20 | acl_ns as acl, | 21 | acl_ns as acl, |
| @@ -26,25 +27,25 @@ pub mod pac { | |||
| 26 | dcnf_ns as dcnf, | 27 | dcnf_ns as dcnf, |
| 27 | dppic_ns as dppic, | 28 | dppic_ns as dppic, |
| 28 | ecb_ns as ecb, | 29 | ecb_ns as ecb, |
| 29 | egu0_ns as egu0, | 30 | egu_ns as egu, |
| 30 | ficr_ns as ficr, | 31 | ficr_ns as ficr, |
| 31 | gpiote_ns as gpiote, | 32 | gpiote_ns as gpiote, |
| 32 | ipc_ns as ipc, | 33 | ipc_ns as ipc, |
| 33 | nvmc_ns as nvmc, | 34 | nvmc_ns as nvmc, |
| 34 | p0_ns as p0, | 35 | gpio_ns as gpio, |
| 35 | power_ns as power, | 36 | power_ns as power, |
| 36 | radio_ns as radio, | 37 | radio_ns as radio, |
| 37 | reset_ns as reset, | 38 | reset_ns as reset, |
| 38 | rng_ns as rng, | 39 | rng_ns as rng, |
| 39 | rtc0_ns as rtc0, | 40 | rtc_ns as rtc, |
| 40 | spim0_ns as spim0, | 41 | spim_ns as spim, |
| 41 | spis0_ns as spis0, | 42 | spis_ns as spis, |
| 42 | swi0_ns as swi0, | 43 | swi_ns as swi, |
| 43 | temp_ns as temp, | 44 | temp_ns as temp, |
| 44 | timer0_ns as timer0, | 45 | timer_ns as timer, |
| 45 | twim0_ns as twim0, | 46 | twim_ns as twim, |
| 46 | twis0_ns as twis0, | 47 | twis_ns as twis, |
| 47 | uarte0_ns as uarte0, | 48 | uarte_ns as uarte, |
| 48 | uicr_ns as uicr, | 49 | uicr_ns as uicr, |
| 49 | vmc_ns as vmc, | 50 | vmc_ns as vmc, |
| 50 | vreqctrl_ns as vreqctrl, | 51 | vreqctrl_ns as vreqctrl, |
| @@ -54,25 +55,17 @@ pub mod pac { | |||
| 54 | ACL_NS as ACL, | 55 | ACL_NS as ACL, |
| 55 | APPMUTEX_NS as APPMUTEX, | 56 | APPMUTEX_NS as APPMUTEX, |
| 56 | APPMUTEX_S as APPMUTEX_S, | 57 | APPMUTEX_S as APPMUTEX_S, |
| 57 | CBP as CBP, | ||
| 58 | CCM_NS as CCM, | 58 | CCM_NS as CCM, |
| 59 | CLOCK_NS as CLOCK, | 59 | CLOCK_NS as CLOCK, |
| 60 | CPUID as CPUID, | ||
| 61 | CTI_NS as CTI, | 60 | CTI_NS as CTI, |
| 62 | CTRLAP_NS as CTRLAP, | 61 | CTRLAP_NS as CTRLAP, |
| 63 | DCB as DCB, | ||
| 64 | DCNF_NS as DCNF, | 62 | DCNF_NS as DCNF, |
| 65 | DPPIC_NS as DPPIC, | 63 | DPPIC_NS as DPPIC, |
| 66 | DWT as DWT, | ||
| 67 | ECB_NS as ECB, | 64 | ECB_NS as ECB, |
| 68 | EGU0_NS as EGU0, | 65 | EGU0_NS as EGU0, |
| 69 | FICR_NS as FICR, | 66 | FICR_NS as FICR, |
| 70 | FPB as FPB, | ||
| 71 | GPIOTE_NS as GPIOTE, | 67 | GPIOTE_NS as GPIOTE, |
| 72 | IPC_NS as IPC, | 68 | IPC_NS as IPC, |
| 73 | ITM as ITM, | ||
| 74 | MPU as MPU, | ||
| 75 | NVIC as NVIC, | ||
| 76 | NVMC_NS as NVMC, | 69 | NVMC_NS as NVMC, |
| 77 | P0_NS as P0, | 70 | P0_NS as P0, |
| 78 | P1_NS as P1, | 71 | P1_NS as P1, |
| @@ -82,19 +75,16 @@ pub mod pac { | |||
| 82 | RNG_NS as RNG, | 75 | RNG_NS as RNG, |
| 83 | RTC0_NS as RTC0, | 76 | RTC0_NS as RTC0, |
| 84 | RTC1_NS as RTC1, | 77 | RTC1_NS as RTC1, |
| 85 | SCB as SCB, | ||
| 86 | SPIM0_NS as SPIM0, | 78 | SPIM0_NS as SPIM0, |
| 87 | SPIS0_NS as SPIS0, | 79 | SPIS0_NS as SPIS0, |
| 88 | SWI0_NS as SWI0, | 80 | SWI0_NS as SWI0, |
| 89 | SWI1_NS as SWI1, | 81 | SWI1_NS as SWI1, |
| 90 | SWI2_NS as SWI2, | 82 | SWI2_NS as SWI2, |
| 91 | SWI3_NS as SWI3, | 83 | SWI3_NS as SWI3, |
| 92 | SYST as SYST, | ||
| 93 | TEMP_NS as TEMP, | 84 | TEMP_NS as TEMP, |
| 94 | TIMER0_NS as TIMER0, | 85 | TIMER0_NS as TIMER0, |
| 95 | TIMER1_NS as TIMER1, | 86 | TIMER1_NS as TIMER1, |
| 96 | TIMER2_NS as TIMER2, | 87 | TIMER2_NS as TIMER2, |
| 97 | TPIU as TPIU, | ||
| 98 | TWIM0_NS as TWIM0, | 88 | TWIM0_NS as TWIM0, |
| 99 | TWIS0_NS as TWIS0, | 89 | TWIS0_NS as TWIS0, |
| 100 | UARTE0_NS as UARTE0, | 90 | UARTE0_NS as UARTE0, |
diff --git a/embassy-nrf/src/chips/nrf9120.rs b/embassy-nrf/src/chips/nrf9120.rs index b53510118..b89570dcd 100644 --- a/embassy-nrf/src/chips/nrf9120.rs +++ b/embassy-nrf/src/chips/nrf9120.rs | |||
| @@ -5,14 +5,16 @@ pub mod pac { | |||
| 5 | // The nRF9120 has a secure and non-secure (NS) mode. | 5 | // The nRF9120 has a secure and non-secure (NS) mode. |
| 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. | 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. |
| 7 | 7 | ||
| 8 | pub use nrf9120_pac::NVIC_PRIO_BITS; | 8 | #[cfg(feature="rt")] |
| 9 | pub use nrf_pac::NVIC_PRIO_BITS; | ||
| 10 | pub use nrf_pac::{common, shared}; | ||
| 9 | 11 | ||
| 10 | #[cfg(feature="rt")] | 12 | #[cfg(feature="rt")] |
| 11 | #[doc(no_inline)] | 13 | #[doc(no_inline)] |
| 12 | pub use nrf9120_pac::interrupt; | 14 | pub use nrf_pac::interrupt; |
| 13 | 15 | ||
| 14 | #[doc(no_inline)] | 16 | #[doc(no_inline)] |
| 15 | pub use nrf9120_pac::{ | 17 | pub use nrf_pac::{ |
| 16 | Interrupt, | 18 | Interrupt, |
| 17 | 19 | ||
| 18 | cc_host_rgf_s as cc_host_rgf, | 20 | cc_host_rgf_s as cc_host_rgf, |
| @@ -20,29 +22,29 @@ pub mod pac { | |||
| 20 | cryptocell_s as cryptocell, | 22 | cryptocell_s as cryptocell, |
| 21 | ctrl_ap_peri_s as ctrl_ap_peri, | 23 | ctrl_ap_peri_s as ctrl_ap_peri, |
| 22 | dppic_ns as dppic, | 24 | dppic_ns as dppic, |
| 23 | egu0_ns as egu0, | 25 | egu_ns as egu, |
| 24 | ficr_s as ficr, | 26 | ficr_s as ficr, |
| 25 | fpu_ns as fpu, | 27 | fpu_ns as fpu, |
| 26 | gpiote0_s as gpiote, | 28 | gpiote_s as gpiote, |
| 27 | i2s_ns as i2s, | 29 | i2s_ns as i2s, |
| 28 | ipc_ns as ipc, | 30 | ipc_ns as ipc, |
| 29 | kmu_ns as kmu, | 31 | kmu_ns as kmu, |
| 30 | nvmc_ns as nvmc, | 32 | nvmc_ns as nvmc, |
| 31 | p0_ns as p0, | 33 | gpio_ns as gpio, |
| 32 | pdm_ns as pdm, | 34 | pdm_ns as pdm, |
| 33 | power_ns as power, | 35 | power_ns as power, |
| 34 | pwm0_ns as pwm0, | 36 | pwm_ns as pwm, |
| 35 | regulators_ns as regulators, | 37 | regulators_ns as regulators, |
| 36 | rtc0_ns as rtc0, | 38 | rtc_ns as rtc, |
| 37 | saadc_ns as saadc, | 39 | saadc_ns as saadc, |
| 38 | spim0_ns as spim0, | 40 | spim_ns as spim, |
| 39 | spis0_ns as spis0, | 41 | spis_ns as spis, |
| 40 | spu_s as spu, | 42 | spu_s as spu, |
| 41 | tad_s as tad, | 43 | tad_s as tad, |
| 42 | timer0_ns as timer0, | 44 | timer_ns as timer, |
| 43 | twim0_ns as twim0, | 45 | twim_ns as twim, |
| 44 | twis0_ns as twis0, | 46 | twis_ns as twis, |
| 45 | uarte0_ns as uarte0, | 47 | uarte_ns as uarte, |
| 46 | uicr_s as uicr, | 48 | uicr_s as uicr, |
| 47 | vmc_ns as vmc, | 49 | vmc_ns as vmc, |
| 48 | wdt_ns as wdt, | 50 | wdt_ns as wdt, |
| @@ -51,7 +53,7 @@ pub mod pac { | |||
| 51 | /// Non-Secure mode (NS) peripherals | 53 | /// Non-Secure mode (NS) peripherals |
| 52 | pub mod ns { | 54 | pub mod ns { |
| 53 | #[doc(no_inline)] | 55 | #[doc(no_inline)] |
| 54 | pub use nrf9120_pac::{ | 56 | pub use nrf_pac::{ |
| 55 | CLOCK_NS as CLOCK, | 57 | CLOCK_NS as CLOCK, |
| 56 | DPPIC_NS as DPPIC, | 58 | DPPIC_NS as DPPIC, |
| 57 | EGU0_NS as EGU0, | 59 | EGU0_NS as EGU0, |
| @@ -108,7 +110,7 @@ pub mod pac { | |||
| 108 | /// Secure mode (S) peripherals | 110 | /// Secure mode (S) peripherals |
| 109 | pub mod s { | 111 | pub mod s { |
| 110 | #[doc(no_inline)] | 112 | #[doc(no_inline)] |
| 111 | pub use nrf9120_pac::{ | 113 | pub use nrf_pac::{ |
| 112 | CC_HOST_RGF_S as CC_HOST_RGF, | 114 | CC_HOST_RGF_S as CC_HOST_RGF, |
| 113 | CLOCK_S as CLOCK, | 115 | CLOCK_S as CLOCK, |
| 114 | CRYPTOCELL_S as CRYPTOCELL, | 116 | CRYPTOCELL_S as CRYPTOCELL, |
| @@ -121,7 +123,7 @@ pub mod pac { | |||
| 121 | EGU4_S as EGU4, | 123 | EGU4_S as EGU4, |
| 122 | EGU5_S as EGU5, | 124 | EGU5_S as EGU5, |
| 123 | FICR_S as FICR, | 125 | FICR_S as FICR, |
| 124 | FPU as FPU, | 126 | FPU_NS as FPU, |
| 125 | GPIOTE0_S as GPIOTE0, | 127 | GPIOTE0_S as GPIOTE0, |
| 126 | I2S_S as I2S, | 128 | I2S_S as I2S, |
| 127 | IPC_S as IPC, | 129 | IPC_S as IPC, |
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 8107ca175..dba3d1ef5 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs | |||
| @@ -5,14 +5,16 @@ pub mod pac { | |||
| 5 | // The nRF9160 has a secure and non-secure (NS) mode. | 5 | // The nRF9160 has a secure and non-secure (NS) mode. |
| 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. | 6 | // To avoid cfg spam, we remove _ns or _s suffixes here. |
| 7 | 7 | ||
| 8 | pub use nrf9160_pac::NVIC_PRIO_BITS; | 8 | #[cfg(feature="rt")] |
| 9 | pub use nrf_pac::NVIC_PRIO_BITS; | ||
| 10 | pub use nrf_pac::{common, shared}; | ||
| 9 | 11 | ||
| 10 | #[cfg(feature="rt")] | 12 | #[cfg(feature="rt")] |
| 11 | #[doc(no_inline)] | 13 | #[doc(no_inline)] |
| 12 | pub use nrf9160_pac::interrupt; | 14 | pub use nrf_pac::interrupt; |
| 13 | 15 | ||
| 14 | #[doc(no_inline)] | 16 | #[doc(no_inline)] |
| 15 | pub use nrf9160_pac::{ | 17 | pub use nrf_pac::{ |
| 16 | Interrupt, | 18 | Interrupt, |
| 17 | 19 | ||
| 18 | cc_host_rgf_s as cc_host_rgf, | 20 | cc_host_rgf_s as cc_host_rgf, |
| @@ -20,29 +22,29 @@ pub mod pac { | |||
| 20 | cryptocell_s as cryptocell, | 22 | cryptocell_s as cryptocell, |
| 21 | ctrl_ap_peri_s as ctrl_ap_peri, | 23 | ctrl_ap_peri_s as ctrl_ap_peri, |
| 22 | dppic_ns as dppic, | 24 | dppic_ns as dppic, |
| 23 | egu0_ns as egu0, | 25 | egu_ns as egu, |
| 24 | ficr_s as ficr, | 26 | ficr_s as ficr, |
| 25 | fpu_ns as fpu, | 27 | fpu_ns as fpu, |
| 26 | gpiote0_s as gpiote, | 28 | gpiote_s as gpiote, |
| 27 | i2s_ns as i2s, | 29 | i2s_ns as i2s, |
| 28 | ipc_ns as ipc, | 30 | ipc_ns as ipc, |
| 29 | kmu_ns as kmu, | 31 | kmu_ns as kmu, |
| 30 | nvmc_ns as nvmc, | 32 | nvmc_ns as nvmc, |
| 31 | p0_ns as p0, | 33 | gpio_ns as gpio, |
| 32 | pdm_ns as pdm, | 34 | pdm_ns as pdm, |
| 33 | power_ns as power, | 35 | power_ns as power, |
| 34 | pwm0_ns as pwm0, | 36 | pwm_ns as pwm, |
| 35 | regulators_ns as regulators, | 37 | regulators_ns as regulators, |
| 36 | rtc0_ns as rtc0, | 38 | rtc_ns as rtc, |
| 37 | saadc_ns as saadc, | 39 | saadc_ns as saadc, |
| 38 | spim0_ns as spim0, | 40 | spim_ns as spim, |
| 39 | spis0_ns as spis0, | 41 | spis_ns as spis, |
| 40 | spu_s as spu, | 42 | spu_s as spu, |
| 41 | tad_s as tad, | 43 | tad_s as tad, |
| 42 | timer0_ns as timer0, | 44 | timer_ns as timer, |
| 43 | twim0_ns as twim0, | 45 | twim_ns as twim, |
| 44 | twis0_ns as twis0, | 46 | twis_ns as twis, |
| 45 | uarte0_ns as uarte0, | 47 | uarte_ns as uarte, |
| 46 | uicr_s as uicr, | 48 | uicr_s as uicr, |
| 47 | vmc_ns as vmc, | 49 | vmc_ns as vmc, |
| 48 | wdt_ns as wdt, | 50 | wdt_ns as wdt, |
| @@ -51,7 +53,7 @@ pub mod pac { | |||
| 51 | /// Non-Secure mode (NS) peripherals | 53 | /// Non-Secure mode (NS) peripherals |
| 52 | pub mod ns { | 54 | pub mod ns { |
| 53 | #[doc(no_inline)] | 55 | #[doc(no_inline)] |
| 54 | pub use nrf9160_pac::{ | 56 | pub use nrf_pac::{ |
| 55 | CLOCK_NS as CLOCK, | 57 | CLOCK_NS as CLOCK, |
| 56 | DPPIC_NS as DPPIC, | 58 | DPPIC_NS as DPPIC, |
| 57 | EGU0_NS as EGU0, | 59 | EGU0_NS as EGU0, |
| @@ -108,7 +110,7 @@ pub mod pac { | |||
| 108 | /// Secure mode (S) peripherals | 110 | /// Secure mode (S) peripherals |
| 109 | pub mod s { | 111 | pub mod s { |
| 110 | #[doc(no_inline)] | 112 | #[doc(no_inline)] |
| 111 | pub use nrf9160_pac::{ | 113 | pub use nrf_pac::{ |
| 112 | CC_HOST_RGF_S as CC_HOST_RGF, | 114 | CC_HOST_RGF_S as CC_HOST_RGF, |
| 113 | CLOCK_S as CLOCK, | 115 | CLOCK_S as CLOCK, |
| 114 | CRYPTOCELL_S as CRYPTOCELL, | 116 | CRYPTOCELL_S as CRYPTOCELL, |
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs index 204446d29..7f9abdac4 100644 --- a/embassy-nrf/src/egu.rs +++ b/embassy-nrf/src/egu.rs | |||
| @@ -34,7 +34,7 @@ impl<'d, T: Instance> Egu<'d, T> { | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | pub(crate) trait SealedInstance { | 36 | pub(crate) trait SealedInstance { |
| 37 | fn regs() -> &'static pac::egu0::RegisterBlock; | 37 | fn regs() -> pac::egu::Egu; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | /// Basic Egu instance. | 40 | /// Basic Egu instance. |
| @@ -47,8 +47,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 47 | macro_rules! impl_egu { | 47 | macro_rules! impl_egu { |
| 48 | ($type:ident, $pac_type:ident, $irq:ident) => { | 48 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 49 | impl crate::egu::SealedInstance for peripherals::$type { | 49 | impl crate::egu::SealedInstance for peripherals::$type { |
| 50 | fn regs() -> &'static pac::egu0::RegisterBlock { | 50 | fn regs() -> pac::egu::Egu { |
| 51 | unsafe { &*pac::$pac_type::ptr() } | 51 | pac::$pac_type |
| 52 | } | 52 | } |
| 53 | } | 53 | } |
| 54 | impl crate::egu::Instance for peripherals::$type { | 54 | impl crate::egu::Instance for peripherals::$type { |
| @@ -68,32 +68,26 @@ impl<'d, T: Instance> Trigger<'d, T> { | |||
| 68 | pub fn task(&self) -> Task<'d> { | 68 | pub fn task(&self) -> Task<'d> { |
| 69 | let nr = self.number as usize; | 69 | let nr = self.number as usize; |
| 70 | let regs = T::regs(); | 70 | let regs = T::regs(); |
| 71 | Task::from_reg(®s.tasks_trigger[nr]) | 71 | Task::from_reg(regs.tasks_trigger(nr)) |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | /// Get event for this trigger to use with PPI. | 74 | /// Get event for this trigger to use with PPI. |
| 75 | pub fn event(&self) -> Event<'d> { | 75 | pub fn event(&self) -> Event<'d> { |
| 76 | let nr = self.number as usize; | 76 | let nr = self.number as usize; |
| 77 | let regs = T::regs(); | 77 | let regs = T::regs(); |
| 78 | Event::from_reg(®s.events_triggered[nr]) | 78 | Event::from_reg(regs.events_triggered(nr)) |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | /// Enable interrupts for this trigger | 81 | /// Enable interrupts for this trigger |
| 82 | pub fn enable_interrupt(&mut self) { | 82 | pub fn enable_interrupt(&mut self) { |
| 83 | let regs = T::regs(); | 83 | let regs = T::regs(); |
| 84 | unsafe { | 84 | regs.intenset().modify(|w| w.set_triggered(self.number as usize, true)); |
| 85 | regs.intenset | ||
| 86 | .modify(|r, w| w.bits(r.bits() | (1 << self.number as usize))) | ||
| 87 | }; | ||
| 88 | } | 85 | } |
| 89 | 86 | ||
| 90 | /// Enable interrupts for this trigger | 87 | /// Enable interrupts for this trigger |
| 91 | pub fn disable_interrupt(&mut self) { | 88 | pub fn disable_interrupt(&mut self) { |
| 92 | let regs = T::regs(); | 89 | let regs = T::regs(); |
| 93 | unsafe { | 90 | regs.intenset().modify(|w| w.set_triggered(self.number as usize, false)); |
| 94 | regs.intenclr | ||
| 95 | .modify(|r, w| w.bits(r.bits() | (1 << self.number as usize))) | ||
| 96 | }; | ||
| 97 | } | 91 | } |
| 98 | } | 92 | } |
| 99 | 93 | ||
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index dbc26ea3f..35b0f2e7b 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -7,14 +7,11 @@ use core::hint::unreachable_unchecked; | |||
| 7 | use cfg_if::cfg_if; | 7 | use cfg_if::cfg_if; |
| 8 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; | 8 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 9 | 9 | ||
| 10 | #[cfg(feature = "nrf51")] | 10 | use crate::pac::common::{Reg, RW}; |
| 11 | use crate::pac::gpio; | 11 | use crate::pac::gpio; |
| 12 | #[cfg(feature = "nrf51")] | 12 | use crate::pac::gpio::vals; |
| 13 | use crate::pac::gpio::pin_cnf::{DRIVE_A, PULL_A}; | 13 | #[cfg(not(feature = "_nrf51"))] |
| 14 | #[cfg(not(feature = "nrf51"))] | 14 | use crate::pac::shared::{regs::Psel, vals::Connect}; |
| 15 | use crate::pac::p0 as gpio; | ||
| 16 | #[cfg(not(feature = "nrf51"))] | ||
| 17 | use crate::pac::p0::pin_cnf::{DRIVE_A, PULL_A}; | ||
| 18 | use crate::{pac, Peripheral}; | 15 | use crate::{pac, Peripheral}; |
| 19 | 16 | ||
| 20 | /// A GPIO port with up to 32 pins. | 17 | /// A GPIO port with up to 32 pins. |
| @@ -103,7 +100,7 @@ impl From<Level> for bool { | |||
| 103 | } | 100 | } |
| 104 | 101 | ||
| 105 | /// Drive strength settings for an output pin. | 102 | /// Drive strength settings for an output pin. |
| 106 | // These numbers match DRIVE_A exactly so hopefully the compiler will unify them. | 103 | // These numbers match vals::Drive exactly so hopefully the compiler will unify them. |
| 107 | #[derive(Clone, Copy, Debug, PartialEq)] | 104 | #[derive(Clone, Copy, Debug, PartialEq)] |
| 108 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 105 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 109 | #[repr(u8)] | 106 | #[repr(u8)] |
| @@ -188,24 +185,24 @@ impl<'d> Output<'d> { | |||
| 188 | } | 185 | } |
| 189 | } | 186 | } |
| 190 | 187 | ||
| 191 | pub(crate) fn convert_drive(drive: OutputDrive) -> DRIVE_A { | 188 | pub(crate) fn convert_drive(drive: OutputDrive) -> vals::Drive { |
| 192 | match drive { | 189 | match drive { |
| 193 | OutputDrive::Standard => DRIVE_A::S0S1, | 190 | OutputDrive::Standard => vals::Drive::S0S1, |
| 194 | OutputDrive::HighDrive0Standard1 => DRIVE_A::H0S1, | 191 | OutputDrive::HighDrive0Standard1 => vals::Drive::H0S1, |
| 195 | OutputDrive::Standard0HighDrive1 => DRIVE_A::S0H1, | 192 | OutputDrive::Standard0HighDrive1 => vals::Drive::S0H1, |
| 196 | OutputDrive::HighDrive => DRIVE_A::H0H1, | 193 | OutputDrive::HighDrive => vals::Drive::H0H1, |
| 197 | OutputDrive::Disconnect0Standard1 => DRIVE_A::D0S1, | 194 | OutputDrive::Disconnect0Standard1 => vals::Drive::D0S1, |
| 198 | OutputDrive::Disconnect0HighDrive1 => DRIVE_A::D0H1, | 195 | OutputDrive::Disconnect0HighDrive1 => vals::Drive::D0H1, |
| 199 | OutputDrive::Standard0Disconnect1 => DRIVE_A::S0D1, | 196 | OutputDrive::Standard0Disconnect1 => vals::Drive::S0D1, |
| 200 | OutputDrive::HighDrive0Disconnect1 => DRIVE_A::H0D1, | 197 | OutputDrive::HighDrive0Disconnect1 => vals::Drive::H0D1, |
| 201 | } | 198 | } |
| 202 | } | 199 | } |
| 203 | 200 | ||
| 204 | fn convert_pull(pull: Pull) -> PULL_A { | 201 | fn convert_pull(pull: Pull) -> vals::Pull { |
| 205 | match pull { | 202 | match pull { |
| 206 | Pull::None => PULL_A::DISABLED, | 203 | Pull::None => vals::Pull::DISABLED, |
| 207 | Pull::Up => PULL_A::PULLUP, | 204 | Pull::Up => vals::Pull::PULLUP, |
| 208 | Pull::Down => PULL_A::PULLDOWN, | 205 | Pull::Down => vals::Pull::PULLDOWN, |
| 209 | } | 206 | } |
| 210 | } | 207 | } |
| 211 | 208 | ||
| @@ -234,12 +231,11 @@ impl<'d> Flex<'d> { | |||
| 234 | #[inline] | 231 | #[inline] |
| 235 | pub fn set_as_input(&mut self, pull: Pull) { | 232 | pub fn set_as_input(&mut self, pull: Pull) { |
| 236 | self.pin.conf().write(|w| { | 233 | self.pin.conf().write(|w| { |
| 237 | w.dir().input(); | 234 | w.set_dir(vals::Dir::INPUT); |
| 238 | w.input().connect(); | 235 | w.set_input(vals::Input::CONNECT); |
| 239 | w.pull().variant(convert_pull(pull)); | 236 | w.set_pull(convert_pull(pull)); |
| 240 | w.drive().s0s1(); | 237 | w.set_drive(vals::Drive::S0S1); |
| 241 | w.sense().disabled(); | 238 | w.set_sense(vals::Sense::DISABLED); |
| 242 | w | ||
| 243 | }); | 239 | }); |
| 244 | } | 240 | } |
| 245 | 241 | ||
| @@ -250,12 +246,11 @@ impl<'d> Flex<'d> { | |||
| 250 | #[inline] | 246 | #[inline] |
| 251 | pub fn set_as_output(&mut self, drive: OutputDrive) { | 247 | pub fn set_as_output(&mut self, drive: OutputDrive) { |
| 252 | self.pin.conf().write(|w| { | 248 | self.pin.conf().write(|w| { |
| 253 | w.dir().output(); | 249 | w.set_dir(vals::Dir::OUTPUT); |
| 254 | w.input().disconnect(); | 250 | w.set_input(vals::Input::DISCONNECT); |
| 255 | w.pull().disabled(); | 251 | w.set_pull(vals::Pull::DISABLED); |
| 256 | w.drive().variant(convert_drive(drive)); | 252 | w.set_drive(convert_drive(drive)); |
| 257 | w.sense().disabled(); | 253 | w.set_sense(vals::Sense::DISABLED); |
| 258 | w | ||
| 259 | }); | 254 | }); |
| 260 | } | 255 | } |
| 261 | 256 | ||
| @@ -271,31 +266,30 @@ impl<'d> Flex<'d> { | |||
| 271 | #[inline] | 266 | #[inline] |
| 272 | pub fn set_as_input_output(&mut self, pull: Pull, drive: OutputDrive) { | 267 | pub fn set_as_input_output(&mut self, pull: Pull, drive: OutputDrive) { |
| 273 | self.pin.conf().write(|w| { | 268 | self.pin.conf().write(|w| { |
| 274 | w.dir().output(); | 269 | w.set_dir(vals::Dir::OUTPUT); |
| 275 | w.input().connect(); | 270 | w.set_input(vals::Input::CONNECT); |
| 276 | w.pull().variant(convert_pull(pull)); | 271 | w.set_pull(convert_pull(pull)); |
| 277 | w.drive().variant(convert_drive(drive)); | 272 | w.set_drive(convert_drive(drive)); |
| 278 | w.sense().disabled(); | 273 | w.set_sense(vals::Sense::DISABLED); |
| 279 | w | ||
| 280 | }); | 274 | }); |
| 281 | } | 275 | } |
| 282 | 276 | ||
| 283 | /// Put the pin into disconnected mode. | 277 | /// Put the pin into disconnected mode. |
| 284 | #[inline] | 278 | #[inline] |
| 285 | pub fn set_as_disconnected(&mut self) { | 279 | pub fn set_as_disconnected(&mut self) { |
| 286 | self.pin.conf().reset(); | 280 | self.pin.conf().write(|_| ()); |
| 287 | } | 281 | } |
| 288 | 282 | ||
| 289 | /// Get whether the pin input level is high. | 283 | /// Get whether the pin input level is high. |
| 290 | #[inline] | 284 | #[inline] |
| 291 | pub fn is_high(&self) -> bool { | 285 | pub fn is_high(&self) -> bool { |
| 292 | !self.is_low() | 286 | self.pin.block().in_().read().pin(self.pin.pin() as _) |
| 293 | } | 287 | } |
| 294 | 288 | ||
| 295 | /// Get whether the pin input level is low. | 289 | /// Get whether the pin input level is low. |
| 296 | #[inline] | 290 | #[inline] |
| 297 | pub fn is_low(&self) -> bool { | 291 | pub fn is_low(&self) -> bool { |
| 298 | self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0 | 292 | !self.is_high() |
| 299 | } | 293 | } |
| 300 | 294 | ||
| 301 | /// Get the pin input level. | 295 | /// Get the pin input level. |
| @@ -338,13 +332,13 @@ impl<'d> Flex<'d> { | |||
| 338 | /// Get whether the output level is set to high. | 332 | /// Get whether the output level is set to high. |
| 339 | #[inline] | 333 | #[inline] |
| 340 | pub fn is_set_high(&self) -> bool { | 334 | pub fn is_set_high(&self) -> bool { |
| 341 | !self.is_set_low() | 335 | self.pin.block().out().read().pin(self.pin.pin() as _) |
| 342 | } | 336 | } |
| 343 | 337 | ||
| 344 | /// Get whether the output level is set to low. | 338 | /// Get whether the output level is set to low. |
| 345 | #[inline] | 339 | #[inline] |
| 346 | pub fn is_set_low(&self) -> bool { | 340 | pub fn is_set_low(&self) -> bool { |
| 347 | self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0 | 341 | !self.is_set_high() |
| 348 | } | 342 | } |
| 349 | 343 | ||
| 350 | /// Get the current output level. | 344 | /// Get the current output level. |
| @@ -356,7 +350,7 @@ impl<'d> Flex<'d> { | |||
| 356 | 350 | ||
| 357 | impl<'d> Drop for Flex<'d> { | 351 | impl<'d> Drop for Flex<'d> { |
| 358 | fn drop(&mut self) { | 352 | fn drop(&mut self) { |
| 359 | self.pin.conf().reset(); | 353 | self.pin.conf().write(|_| ()) |
| 360 | } | 354 | } |
| 361 | } | 355 | } |
| 362 | 356 | ||
| @@ -375,35 +369,33 @@ pub(crate) trait SealedPin { | |||
| 375 | } | 369 | } |
| 376 | 370 | ||
| 377 | #[inline] | 371 | #[inline] |
| 378 | fn block(&self) -> &gpio::RegisterBlock { | 372 | fn block(&self) -> gpio::Gpio { |
| 379 | unsafe { | 373 | match self.pin_port() / 32 { |
| 380 | match self.pin_port() / 32 { | 374 | #[cfg(feature = "_nrf51")] |
| 381 | #[cfg(feature = "nrf51")] | 375 | 0 => pac::GPIO, |
| 382 | 0 => &*pac::GPIO::ptr(), | 376 | #[cfg(not(feature = "_nrf51"))] |
| 383 | #[cfg(not(feature = "nrf51"))] | 377 | 0 => pac::P0, |
| 384 | 0 => &*pac::P0::ptr(), | 378 | #[cfg(feature = "_gpio-p1")] |
| 385 | #[cfg(feature = "_gpio-p1")] | 379 | 1 => pac::P1, |
| 386 | 1 => &*pac::P1::ptr(), | 380 | _ => unsafe { unreachable_unchecked() }, |
| 387 | _ => unreachable_unchecked(), | ||
| 388 | } | ||
| 389 | } | 381 | } |
| 390 | } | 382 | } |
| 391 | 383 | ||
| 392 | #[inline] | 384 | #[inline] |
| 393 | fn conf(&self) -> &gpio::PIN_CNF { | 385 | fn conf(&self) -> Reg<gpio::regs::PinCnf, RW> { |
| 394 | &self.block().pin_cnf[self._pin() as usize] | 386 | self.block().pin_cnf(self._pin() as usize) |
| 395 | } | 387 | } |
| 396 | 388 | ||
| 397 | /// Set the output as high. | 389 | /// Set the output as high. |
| 398 | #[inline] | 390 | #[inline] |
| 399 | fn set_high(&self) { | 391 | fn set_high(&self) { |
| 400 | unsafe { self.block().outset.write(|w| w.bits(1u32 << self._pin())) } | 392 | self.block().outset().write(|w| w.set_pin(self._pin() as _, true)) |
| 401 | } | 393 | } |
| 402 | 394 | ||
| 403 | /// Set the output as low. | 395 | /// Set the output as low. |
| 404 | #[inline] | 396 | #[inline] |
| 405 | fn set_low(&self) { | 397 | fn set_low(&self) { |
| 406 | unsafe { self.block().outclr.write(|w| w.bits(1u32 << self._pin())) } | 398 | self.block().outclr().write(|w| w.set_pin(self._pin() as _, true)) |
| 407 | } | 399 | } |
| 408 | } | 400 | } |
| 409 | 401 | ||
| @@ -429,8 +421,9 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + SealedPin + Sized + 'static | |||
| 429 | 421 | ||
| 430 | /// Peripheral port register value | 422 | /// Peripheral port register value |
| 431 | #[inline] | 423 | #[inline] |
| 432 | fn psel_bits(&self) -> u32 { | 424 | #[cfg(not(feature = "_nrf51"))] |
| 433 | self.pin_port() as u32 | 425 | fn psel_bits(&self) -> pac::shared::regs::Psel { |
| 426 | pac::shared::regs::Psel(self.pin_port() as u32) | ||
| 434 | } | 427 | } |
| 435 | 428 | ||
| 436 | /// Convert from concrete pin type PX_XX to type erased `AnyPin`. | 429 | /// Convert from concrete pin type PX_XX to type erased `AnyPin`. |
| @@ -471,26 +464,30 @@ impl SealedPin for AnyPin { | |||
| 471 | 464 | ||
| 472 | #[cfg(not(feature = "_nrf51"))] | 465 | #[cfg(not(feature = "_nrf51"))] |
| 473 | pub(crate) trait PselBits { | 466 | pub(crate) trait PselBits { |
| 474 | fn psel_bits(&self) -> u32; | 467 | fn psel_bits(&self) -> pac::shared::regs::Psel; |
| 475 | } | 468 | } |
| 476 | 469 | ||
| 477 | #[cfg(not(feature = "_nrf51"))] | 470 | #[cfg(not(feature = "_nrf51"))] |
| 478 | impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> { | 471 | impl<'a, P: Pin> PselBits for Option<PeripheralRef<'a, P>> { |
| 479 | #[inline] | 472 | #[inline] |
| 480 | fn psel_bits(&self) -> u32 { | 473 | fn psel_bits(&self) -> pac::shared::regs::Psel { |
| 481 | match self { | 474 | match self { |
| 482 | Some(pin) => pin.psel_bits(), | 475 | Some(pin) => pin.psel_bits(), |
| 483 | None => 1u32 << 31, | 476 | None => DISCONNECTED, |
| 484 | } | 477 | } |
| 485 | } | 478 | } |
| 486 | } | 479 | } |
| 487 | 480 | ||
| 481 | #[cfg(not(feature = "_nrf51"))] | ||
| 482 | pub(crate) const DISCONNECTED: Psel = Psel(1 << 31); | ||
| 483 | |||
| 484 | #[cfg(not(feature = "_nrf51"))] | ||
| 488 | #[allow(dead_code)] | 485 | #[allow(dead_code)] |
| 489 | pub(crate) fn deconfigure_pin(psel_bits: u32) { | 486 | pub(crate) fn deconfigure_pin(psel: Psel) { |
| 490 | if psel_bits & 0x8000_0000 != 0 { | 487 | if psel.connect() == Connect::DISCONNECTED { |
| 491 | return; | 488 | return; |
| 492 | } | 489 | } |
| 493 | unsafe { AnyPin::steal(psel_bits as _).conf().reset() } | 490 | unsafe { AnyPin::steal(psel.0 as _).conf().write(|_| ()) } |
| 494 | } | 491 | } |
| 495 | 492 | ||
| 496 | // ==================== | 493 | // ==================== |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 9d97c7be9..87bb405f4 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -9,10 +9,14 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 9 | 9 | ||
| 10 | use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; | 10 | use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; |
| 11 | use crate::interrupt::InterruptExt; | 11 | use crate::interrupt::InterruptExt; |
| 12 | #[cfg(not(feature = "_nrf51"))] | ||
| 13 | use crate::pac::gpio::vals::Detectmode; | ||
| 14 | use crate::pac::gpio::vals::Sense; | ||
| 15 | use crate::pac::gpiote::vals::{Mode, Outinit, Polarity}; | ||
| 12 | use crate::ppi::{Event, Task}; | 16 | use crate::ppi::{Event, Task}; |
| 13 | use crate::{interrupt, pac, peripherals}; | 17 | use crate::{interrupt, pac, peripherals}; |
| 14 | 18 | ||
| 15 | #[cfg(feature = "nrf51")] | 19 | #[cfg(feature = "_nrf51")] |
| 16 | /// Amount of GPIOTE channels in the chip. | 20 | /// Amount of GPIOTE channels in the chip. |
| 17 | const CHANNEL_COUNT: usize = 4; | 21 | const CHANNEL_COUNT: usize = 4; |
| 18 | #[cfg(not(feature = "_nrf51"))] | 22 | #[cfg(not(feature = "_nrf51"))] |
| @@ -51,14 +55,14 @@ pub enum OutputChannelPolarity { | |||
| 51 | Toggle, | 55 | Toggle, |
| 52 | } | 56 | } |
| 53 | 57 | ||
| 54 | fn regs() -> &'static pac::gpiote::RegisterBlock { | 58 | fn regs() -> pac::gpiote::Gpiote { |
| 55 | cfg_if::cfg_if! { | 59 | cfg_if::cfg_if! { |
| 56 | if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s", feature="nrf9120-s"))] { | 60 | if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s", feature="nrf9120-s"))] { |
| 57 | unsafe { &*pac::GPIOTE0::ptr() } | 61 | pac::GPIOTE0 |
| 58 | } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns", feature="nrf9120-ns"))] { | 62 | } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns", feature="nrf9120-ns"))] { |
| 59 | unsafe { &*pac::GPIOTE1::ptr() } | 63 | pac::GPIOTE1 |
| 60 | } else { | 64 | } else { |
| 61 | unsafe { &*pac::GPIOTE::ptr() } | 65 | pac::GPIOTE |
| 62 | } | 66 | } |
| 63 | } | 67 | } |
| 64 | } | 68 | } |
| @@ -68,15 +72,15 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | |||
| 68 | #[cfg(not(feature = "_nrf51"))] | 72 | #[cfg(not(feature = "_nrf51"))] |
| 69 | { | 73 | { |
| 70 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 74 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] |
| 71 | let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] }; | 75 | let ports = &[pac::P0, pac::P1]; |
| 72 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] | 76 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] |
| 73 | let ports = unsafe { &[&*pac::P0::ptr()] }; | 77 | let ports = &[pac::P0]; |
| 74 | 78 | ||
| 75 | for &p in ports { | 79 | for &p in ports { |
| 76 | // Enable latched detection | 80 | // Enable latched detection |
| 77 | p.detectmode.write(|w| w.detectmode().ldetect()); | 81 | p.detectmode().write(|w| w.set_detectmode(Detectmode::LDETECT)); |
| 78 | // Clear latch | 82 | // Clear latch |
| 79 | p.latch.write(|w| unsafe { w.bits(0xFFFFFFFF) }) | 83 | p.latch().write(|w| w.0 = 0xFFFFFFFF) |
| 80 | } | 84 | } |
| 81 | } | 85 | } |
| 82 | 86 | ||
| @@ -93,7 +97,7 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | |||
| 93 | unsafe { irq.enable() }; | 97 | unsafe { irq.enable() }; |
| 94 | 98 | ||
| 95 | let g = regs(); | 99 | let g = regs(); |
| 96 | g.intenset.write(|w| w.port().set()); | 100 | g.intenset().write(|w| w.set_port(true)); |
| 97 | } | 101 | } |
| 98 | 102 | ||
| 99 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] | 103 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] |
| @@ -121,47 +125,47 @@ unsafe fn handle_gpiote_interrupt() { | |||
| 121 | let g = regs(); | 125 | let g = regs(); |
| 122 | 126 | ||
| 123 | for i in 0..CHANNEL_COUNT { | 127 | for i in 0..CHANNEL_COUNT { |
| 124 | if g.events_in[i].read().bits() != 0 { | 128 | if g.events_in(i).read() != 0 { |
| 125 | g.intenclr.write(|w| w.bits(1 << i)); | 129 | g.intenclr().write(|w| w.0 = 1 << i); |
| 126 | CHANNEL_WAKERS[i].wake(); | 130 | CHANNEL_WAKERS[i].wake(); |
| 127 | } | 131 | } |
| 128 | } | 132 | } |
| 129 | 133 | ||
| 130 | if g.events_port.read().bits() != 0 { | 134 | if g.events_port().read() != 0 { |
| 131 | g.events_port.write(|w| w); | 135 | g.events_port().write_value(0); |
| 132 | 136 | ||
| 133 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 137 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] |
| 134 | let ports = &[&*pac::P0::ptr(), &*pac::P1::ptr()]; | 138 | let ports = &[pac::P0, pac::P1]; |
| 135 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] | 139 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] |
| 136 | let ports = &[&*pac::P0::ptr()]; | 140 | let ports = &[pac::P0]; |
| 137 | #[cfg(feature = "_nrf51")] | 141 | #[cfg(feature = "_nrf51")] |
| 138 | let ports = unsafe { &[&*pac::GPIO::ptr()] }; | 142 | let ports = &[pac::GPIO]; |
| 139 | 143 | ||
| 140 | #[cfg(feature = "_nrf51")] | 144 | #[cfg(feature = "_nrf51")] |
| 141 | for (port, &p) in ports.iter().enumerate() { | 145 | for (port, &p) in ports.iter().enumerate() { |
| 142 | let inp = p.in_.read().bits(); | 146 | let inp = p.in_().read(); |
| 143 | for pin in 0..32 { | 147 | for pin in 0..32 { |
| 144 | let fired = match p.pin_cnf[pin as usize].read().sense().variant() { | 148 | let fired = match p.pin_cnf(pin as usize).read().sense() { |
| 145 | Some(pac::gpio::pin_cnf::SENSE_A::HIGH) => inp & (1 << pin) != 0, | 149 | Sense::HIGH => inp.pin(pin), |
| 146 | Some(pac::gpio::pin_cnf::SENSE_A::LOW) => inp & (1 << pin) == 0, | 150 | Sense::LOW => !inp.pin(pin), |
| 147 | _ => false, | 151 | _ => false, |
| 148 | }; | 152 | }; |
| 149 | 153 | ||
| 150 | if fired { | 154 | if fired { |
| 151 | PORT_WAKERS[port * 32 + pin as usize].wake(); | 155 | PORT_WAKERS[port * 32 + pin as usize].wake(); |
| 152 | p.pin_cnf[pin as usize].modify(|_, w| w.sense().disabled()); | 156 | p.pin_cnf(pin as usize).modify(|w| w.set_sense(Sense::DISABLED)); |
| 153 | } | 157 | } |
| 154 | } | 158 | } |
| 155 | } | 159 | } |
| 156 | 160 | ||
| 157 | #[cfg(not(feature = "_nrf51"))] | 161 | #[cfg(not(feature = "_nrf51"))] |
| 158 | for (port, &p) in ports.iter().enumerate() { | 162 | for (port, &p) in ports.iter().enumerate() { |
| 159 | let bits = p.latch.read().bits(); | 163 | let bits = p.latch().read().0; |
| 160 | for pin in BitIter(bits) { | 164 | for pin in BitIter(bits) { |
| 161 | p.pin_cnf[pin as usize].modify(|_, w| w.sense().disabled()); | 165 | p.pin_cnf(pin as usize).modify(|w| w.set_sense(Sense::DISABLED)); |
| 162 | PORT_WAKERS[port * 32 + pin as usize].wake(); | 166 | PORT_WAKERS[port * 32 + pin as usize].wake(); |
| 163 | } | 167 | } |
| 164 | p.latch.write(|w| w.bits(bits)); | 168 | p.latch().write(|w| w.0 = bits); |
| 165 | } | 169 | } |
| 166 | } | 170 | } |
| 167 | } | 171 | } |
| @@ -194,8 +198,8 @@ impl<'d> Drop for InputChannel<'d> { | |||
| 194 | fn drop(&mut self) { | 198 | fn drop(&mut self) { |
| 195 | let g = regs(); | 199 | let g = regs(); |
| 196 | let num = self.ch.number(); | 200 | let num = self.ch.number(); |
| 197 | g.config[num].write(|w| w.mode().disabled()); | 201 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); |
| 198 | g.intenclr.write(|w| unsafe { w.bits(1 << num) }); | 202 | g.intenclr().write(|w| w.0 = 1 << num); |
| 199 | } | 203 | } |
| 200 | } | 204 | } |
| 201 | 205 | ||
| @@ -207,22 +211,23 @@ impl<'d> InputChannel<'d> { | |||
| 207 | let g = regs(); | 211 | let g = regs(); |
| 208 | let num = ch.number(); | 212 | let num = ch.number(); |
| 209 | 213 | ||
| 210 | g.config[num].write(|w| { | 214 | g.config(num).write(|w| { |
| 215 | w.set_mode(Mode::EVENT); | ||
| 211 | match polarity { | 216 | match polarity { |
| 212 | InputChannelPolarity::HiToLo => w.mode().event().polarity().hi_to_lo(), | 217 | InputChannelPolarity::HiToLo => w.set_polarity(Polarity::HI_TO_LO), |
| 213 | InputChannelPolarity::LoToHi => w.mode().event().polarity().lo_to_hi(), | 218 | InputChannelPolarity::LoToHi => w.set_polarity(Polarity::LO_TO_HI), |
| 214 | InputChannelPolarity::None => w.mode().event().polarity().none(), | 219 | InputChannelPolarity::None => w.set_polarity(Polarity::NONE), |
| 215 | InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(), | 220 | InputChannelPolarity::Toggle => w.set_polarity(Polarity::TOGGLE), |
| 216 | }; | 221 | }; |
| 217 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 222 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] |
| 218 | w.port().bit(match pin.pin.pin.port() { | 223 | w.set_port(match pin.pin.pin.port() { |
| 219 | crate::gpio::Port::Port0 => false, | 224 | crate::gpio::Port::Port0 => false, |
| 220 | crate::gpio::Port::Port1 => true, | 225 | crate::gpio::Port::Port1 => true, |
| 221 | }); | 226 | }); |
| 222 | unsafe { w.psel().bits(pin.pin.pin.pin()) } | 227 | w.set_psel(pin.pin.pin.pin()); |
| 223 | }); | 228 | }); |
| 224 | 229 | ||
| 225 | g.events_in[num].reset(); | 230 | g.events_in(num).write_value(0); |
| 226 | 231 | ||
| 227 | InputChannel { ch: ch.map_into(), pin } | 232 | InputChannel { ch: ch.map_into(), pin } |
| 228 | } | 233 | } |
| @@ -233,13 +238,13 @@ impl<'d> InputChannel<'d> { | |||
| 233 | let num = self.ch.number(); | 238 | let num = self.ch.number(); |
| 234 | 239 | ||
| 235 | // Enable interrupt | 240 | // Enable interrupt |
| 236 | g.events_in[num].reset(); | 241 | g.events_in(num).write_value(0); |
| 237 | g.intenset.write(|w| unsafe { w.bits(1 << num) }); | 242 | g.intenset().write(|w| w.0 = 1 << num); |
| 238 | 243 | ||
| 239 | poll_fn(|cx| { | 244 | poll_fn(|cx| { |
| 240 | CHANNEL_WAKERS[num].register(cx.waker()); | 245 | CHANNEL_WAKERS[num].register(cx.waker()); |
| 241 | 246 | ||
| 242 | if g.events_in[num].read().bits() != 0 { | 247 | if g.events_in(num).read() != 0 { |
| 243 | Poll::Ready(()) | 248 | Poll::Ready(()) |
| 244 | } else { | 249 | } else { |
| 245 | Poll::Pending | 250 | Poll::Pending |
| @@ -251,7 +256,7 @@ impl<'d> InputChannel<'d> { | |||
| 251 | /// Returns the IN event, for use with PPI. | 256 | /// Returns the IN event, for use with PPI. |
| 252 | pub fn event_in(&self) -> Event<'d> { | 257 | pub fn event_in(&self) -> Event<'d> { |
| 253 | let g = regs(); | 258 | let g = regs(); |
| 254 | Event::from_reg(&g.events_in[self.ch.number()]) | 259 | Event::from_reg(g.events_in(self.ch.number())) |
| 255 | } | 260 | } |
| 256 | } | 261 | } |
| 257 | 262 | ||
| @@ -265,8 +270,8 @@ impl<'d> Drop for OutputChannel<'d> { | |||
| 265 | fn drop(&mut self) { | 270 | fn drop(&mut self) { |
| 266 | let g = regs(); | 271 | let g = regs(); |
| 267 | let num = self.ch.number(); | 272 | let num = self.ch.number(); |
| 268 | g.config[num].write(|w| w.mode().disabled()); | 273 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); |
| 269 | g.intenclr.write(|w| unsafe { w.bits(1 << num) }); | 274 | g.intenclr().write(|w| w.0 = 1 << num); |
| 270 | } | 275 | } |
| 271 | } | 276 | } |
| 272 | 277 | ||
| @@ -277,23 +282,23 @@ impl<'d> OutputChannel<'d> { | |||
| 277 | let g = regs(); | 282 | let g = regs(); |
| 278 | let num = ch.number(); | 283 | let num = ch.number(); |
| 279 | 284 | ||
| 280 | g.config[num].write(|w| { | 285 | g.config(num).write(|w| { |
| 281 | w.mode().task(); | 286 | w.set_mode(Mode::TASK); |
| 282 | match pin.is_set_high() { | 287 | match pin.is_set_high() { |
| 283 | true => w.outinit().high(), | 288 | true => w.set_outinit(Outinit::HIGH), |
| 284 | false => w.outinit().low(), | 289 | false => w.set_outinit(Outinit::LOW), |
| 285 | }; | 290 | }; |
| 286 | match polarity { | 291 | match polarity { |
| 287 | OutputChannelPolarity::Set => w.polarity().lo_to_hi(), | 292 | OutputChannelPolarity::Set => w.set_polarity(Polarity::HI_TO_LO), |
| 288 | OutputChannelPolarity::Clear => w.polarity().hi_to_lo(), | 293 | OutputChannelPolarity::Clear => w.set_polarity(Polarity::LO_TO_HI), |
| 289 | OutputChannelPolarity::Toggle => w.polarity().toggle(), | 294 | OutputChannelPolarity::Toggle => w.set_polarity(Polarity::TOGGLE), |
| 290 | }; | 295 | }; |
| 291 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 296 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] |
| 292 | w.port().bit(match pin.pin.pin.port() { | 297 | w.set_port(match pin.pin.pin.port() { |
| 293 | crate::gpio::Port::Port0 => false, | 298 | crate::gpio::Port::Port0 => false, |
| 294 | crate::gpio::Port::Port1 => true, | 299 | crate::gpio::Port::Port1 => true, |
| 295 | }); | 300 | }); |
| 296 | unsafe { w.psel().bits(pin.pin.pin.pin()) } | 301 | w.set_psel(pin.pin.pin.pin()); |
| 297 | }); | 302 | }); |
| 298 | 303 | ||
| 299 | OutputChannel { | 304 | OutputChannel { |
| @@ -305,41 +310,41 @@ impl<'d> OutputChannel<'d> { | |||
| 305 | /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle). | 310 | /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle). |
| 306 | pub fn out(&self) { | 311 | pub fn out(&self) { |
| 307 | let g = regs(); | 312 | let g = regs(); |
| 308 | g.tasks_out[self.ch.number()].write(|w| unsafe { w.bits(1) }); | 313 | g.tasks_out(self.ch.number()).write_value(1); |
| 309 | } | 314 | } |
| 310 | 315 | ||
| 311 | /// Triggers the SET task (set associated pin high). | 316 | /// Triggers the SET task (set associated pin high). |
| 312 | #[cfg(not(feature = "nrf51"))] | 317 | #[cfg(not(feature = "_nrf51"))] |
| 313 | pub fn set(&self) { | 318 | pub fn set(&self) { |
| 314 | let g = regs(); | 319 | let g = regs(); |
| 315 | g.tasks_set[self.ch.number()].write(|w| unsafe { w.bits(1) }); | 320 | g.tasks_set(self.ch.number()).write_value(1); |
| 316 | } | 321 | } |
| 317 | 322 | ||
| 318 | /// Triggers the CLEAR task (set associated pin low). | 323 | /// Triggers the CLEAR task (set associated pin low). |
| 319 | #[cfg(not(feature = "nrf51"))] | 324 | #[cfg(not(feature = "_nrf51"))] |
| 320 | pub fn clear(&self) { | 325 | pub fn clear(&self) { |
| 321 | let g = regs(); | 326 | let g = regs(); |
| 322 | g.tasks_clr[self.ch.number()].write(|w| unsafe { w.bits(1) }); | 327 | g.tasks_clr(self.ch.number()).write_value(1); |
| 323 | } | 328 | } |
| 324 | 329 | ||
| 325 | /// Returns the OUT task, for use with PPI. | 330 | /// Returns the OUT task, for use with PPI. |
| 326 | pub fn task_out(&self) -> Task<'d> { | 331 | pub fn task_out(&self) -> Task<'d> { |
| 327 | let g = regs(); | 332 | let g = regs(); |
| 328 | Task::from_reg(&g.tasks_out[self.ch.number()]) | 333 | Task::from_reg(g.tasks_out(self.ch.number())) |
| 329 | } | 334 | } |
| 330 | 335 | ||
| 331 | /// Returns the CLR task, for use with PPI. | 336 | /// Returns the CLR task, for use with PPI. |
| 332 | #[cfg(not(feature = "nrf51"))] | 337 | #[cfg(not(feature = "_nrf51"))] |
| 333 | pub fn task_clr(&self) -> Task<'d> { | 338 | pub fn task_clr(&self) -> Task<'d> { |
| 334 | let g = regs(); | 339 | let g = regs(); |
| 335 | Task::from_reg(&g.tasks_clr[self.ch.number()]) | 340 | Task::from_reg(g.tasks_clr(self.ch.number())) |
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | /// Returns the SET task, for use with PPI. | 343 | /// Returns the SET task, for use with PPI. |
| 339 | #[cfg(not(feature = "nrf51"))] | 344 | #[cfg(not(feature = "_nrf51"))] |
| 340 | pub fn task_set(&self) -> Task<'d> { | 345 | pub fn task_set(&self) -> Task<'d> { |
| 341 | let g = regs(); | 346 | let g = regs(); |
| 342 | Task::from_reg(&g.tasks_set[self.ch.number()]) | 347 | Task::from_reg(g.tasks_set(self.ch.number())) |
| 343 | } | 348 | } |
| 344 | } | 349 | } |
| 345 | 350 | ||
| @@ -362,7 +367,7 @@ impl<'a> Unpin for PortInputFuture<'a> {} | |||
| 362 | 367 | ||
| 363 | impl<'a> Drop for PortInputFuture<'a> { | 368 | impl<'a> Drop for PortInputFuture<'a> { |
| 364 | fn drop(&mut self) { | 369 | fn drop(&mut self) { |
| 365 | self.pin.conf().modify(|_, w| w.sense().disabled()); | 370 | self.pin.conf().modify(|w| w.set_sense(Sense::DISABLED)); |
| 366 | } | 371 | } |
| 367 | } | 372 | } |
| 368 | 373 | ||
| @@ -372,7 +377,7 @@ impl<'a> Future for PortInputFuture<'a> { | |||
| 372 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | 377 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 373 | PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker()); | 378 | PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker()); |
| 374 | 379 | ||
| 375 | if self.pin.conf().read().sense().is_disabled() { | 380 | if self.pin.conf().read().sense() == Sense::DISABLED { |
| 376 | Poll::Ready(()) | 381 | Poll::Ready(()) |
| 377 | } else { | 382 | } else { |
| 378 | Poll::Pending | 383 | Poll::Pending |
| @@ -410,13 +415,13 @@ impl<'d> Input<'d> { | |||
| 410 | impl<'d> Flex<'d> { | 415 | impl<'d> Flex<'d> { |
| 411 | /// Wait until the pin is high. If it is already high, return immediately. | 416 | /// Wait until the pin is high. If it is already high, return immediately. |
| 412 | pub async fn wait_for_high(&mut self) { | 417 | pub async fn wait_for_high(&mut self) { |
| 413 | self.pin.conf().modify(|_, w| w.sense().high()); | 418 | self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); |
| 414 | PortInputFuture::new(&mut self.pin).await | 419 | PortInputFuture::new(&mut self.pin).await |
| 415 | } | 420 | } |
| 416 | 421 | ||
| 417 | /// Wait until the pin is low. If it is already low, return immediately. | 422 | /// Wait until the pin is low. If it is already low, return immediately. |
| 418 | pub async fn wait_for_low(&mut self) { | 423 | pub async fn wait_for_low(&mut self) { |
| 419 | self.pin.conf().modify(|_, w| w.sense().low()); | 424 | self.pin.conf().modify(|w| w.set_sense(Sense::LOW)); |
| 420 | PortInputFuture::new(&mut self.pin).await | 425 | PortInputFuture::new(&mut self.pin).await |
| 421 | } | 426 | } |
| 422 | 427 | ||
| @@ -435,9 +440,9 @@ impl<'d> Flex<'d> { | |||
| 435 | /// Wait for the pin to undergo any transition, i.e low to high OR high to low. | 440 | /// Wait for the pin to undergo any transition, i.e low to high OR high to low. |
| 436 | pub async fn wait_for_any_edge(&mut self) { | 441 | pub async fn wait_for_any_edge(&mut self) { |
| 437 | if self.is_high() { | 442 | if self.is_high() { |
| 438 | self.pin.conf().modify(|_, w| w.sense().low()); | 443 | self.pin.conf().modify(|w| w.set_sense(Sense::LOW)); |
| 439 | } else { | 444 | } else { |
| 440 | self.pin.conf().modify(|_, w| w.sense().high()); | 445 | self.pin.conf().modify(|w| w.set_sense(Sense::HIGH)); |
| 441 | } | 446 | } |
| 442 | PortInputFuture::new(&mut self.pin).await | 447 | PortInputFuture::new(&mut self.pin).await |
| 443 | } | 448 | } |
| @@ -504,13 +509,13 @@ impl_channel!(GPIOTE_CH0, 0); | |||
| 504 | impl_channel!(GPIOTE_CH1, 1); | 509 | impl_channel!(GPIOTE_CH1, 1); |
| 505 | impl_channel!(GPIOTE_CH2, 2); | 510 | impl_channel!(GPIOTE_CH2, 2); |
| 506 | impl_channel!(GPIOTE_CH3, 3); | 511 | impl_channel!(GPIOTE_CH3, 3); |
| 507 | #[cfg(not(feature = "nrf51"))] | 512 | #[cfg(not(feature = "_nrf51"))] |
| 508 | impl_channel!(GPIOTE_CH4, 4); | 513 | impl_channel!(GPIOTE_CH4, 4); |
| 509 | #[cfg(not(feature = "nrf51"))] | 514 | #[cfg(not(feature = "_nrf51"))] |
| 510 | impl_channel!(GPIOTE_CH5, 5); | 515 | impl_channel!(GPIOTE_CH5, 5); |
| 511 | #[cfg(not(feature = "nrf51"))] | 516 | #[cfg(not(feature = "_nrf51"))] |
| 512 | impl_channel!(GPIOTE_CH6, 6); | 517 | impl_channel!(GPIOTE_CH6, 6); |
| 513 | #[cfg(not(feature = "nrf51"))] | 518 | #[cfg(not(feature = "_nrf51"))] |
| 514 | impl_channel!(GPIOTE_CH7, 7); | 519 | impl_channel!(GPIOTE_CH7, 7); |
| 515 | 520 | ||
| 516 | // ==================== | 521 | // ==================== |
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index 5f565a9b7..384a1637b 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs | |||
| @@ -13,11 +13,11 @@ use embassy_hal_internal::drop::OnDrop; | |||
| 13 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 13 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 14 | use embassy_sync::waitqueue::AtomicWaker; | 14 | use embassy_sync::waitqueue::AtomicWaker; |
| 15 | 15 | ||
| 16 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 16 | use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::i2s::RegisterBlock; | 18 | use crate::pac::i2s::vals; |
| 19 | use crate::util::slice_in_ram_or; | 19 | use crate::util::slice_in_ram_or; |
| 20 | use crate::{interrupt, Peripheral, EASY_DMA_SIZE}; | 20 | use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; |
| 21 | 21 | ||
| 22 | /// Type alias for `MultiBuffering` with 2 buffers. | 22 | /// Type alias for `MultiBuffering` with 2 buffers. |
| 23 | pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; | 23 | pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; |
| @@ -117,9 +117,20 @@ pub enum MckFreq { | |||
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | impl MckFreq { | 119 | impl MckFreq { |
| 120 | const REGISTER_VALUES: &'static [u32] = &[ | 120 | const REGISTER_VALUES: &'static [vals::Mckfreq] = &[ |
| 121 | 0x20000000, 0x18000000, 0x16000000, 0x11000000, 0x10000000, 0x0C000000, 0x0B000000, 0x08800000, 0x08400000, | 121 | vals::Mckfreq::_32MDIV8, |
| 122 | 0x08000000, 0x06000000, 0x04100000, 0x020C0000, | 122 | vals::Mckfreq::_32MDIV10, |
| 123 | vals::Mckfreq::_32MDIV11, | ||
| 124 | vals::Mckfreq::_32MDIV15, | ||
| 125 | vals::Mckfreq::_32MDIV16, | ||
| 126 | vals::Mckfreq::_32MDIV21, | ||
| 127 | vals::Mckfreq::_32MDIV23, | ||
| 128 | vals::Mckfreq::_32MDIV30, | ||
| 129 | vals::Mckfreq::_32MDIV31, | ||
| 130 | vals::Mckfreq::_32MDIV32, | ||
| 131 | vals::Mckfreq::_32MDIV42, | ||
| 132 | vals::Mckfreq::_32MDIV63, | ||
| 133 | vals::Mckfreq::_32MDIV125, | ||
| 123 | ]; | 134 | ]; |
| 124 | 135 | ||
| 125 | const FREQUENCIES: &'static [u32] = &[ | 136 | const FREQUENCIES: &'static [u32] = &[ |
| @@ -128,7 +139,7 @@ impl MckFreq { | |||
| 128 | ]; | 139 | ]; |
| 129 | 140 | ||
| 130 | /// Return the value that needs to be written to the register. | 141 | /// Return the value that needs to be written to the register. |
| 131 | pub fn to_register_value(&self) -> u32 { | 142 | pub fn to_register_value(&self) -> vals::Mckfreq { |
| 132 | Self::REGISTER_VALUES[usize::from(*self)] | 143 | Self::REGISTER_VALUES[usize::from(*self)] |
| 133 | } | 144 | } |
| 134 | 145 | ||
| @@ -174,8 +185,8 @@ impl Ratio { | |||
| 174 | const RATIOS: &'static [u32] = &[32, 48, 64, 96, 128, 192, 256, 384, 512]; | 185 | const RATIOS: &'static [u32] = &[32, 48, 64, 96, 128, 192, 256, 384, 512]; |
| 175 | 186 | ||
| 176 | /// Return the value that needs to be written to the register. | 187 | /// Return the value that needs to be written to the register. |
| 177 | pub fn to_register_value(&self) -> u8 { | 188 | pub fn to_register_value(&self) -> vals::Ratio { |
| 178 | usize::from(*self) as u8 | 189 | vals::Ratio::from_bits(*self as u8) |
| 179 | } | 190 | } |
| 180 | 191 | ||
| 181 | /// Return the divisor for this ratio | 192 | /// Return the divisor for this ratio |
| @@ -304,9 +315,9 @@ pub enum SampleWidth { | |||
| 304 | _24bit, | 315 | _24bit, |
| 305 | } | 316 | } |
| 306 | 317 | ||
| 307 | impl From<SampleWidth> for u8 { | 318 | impl From<SampleWidth> for vals::Swidth { |
| 308 | fn from(variant: SampleWidth) -> Self { | 319 | fn from(variant: SampleWidth) -> Self { |
| 309 | variant as _ | 320 | vals::Swidth::from_bits(variant as u8) |
| 310 | } | 321 | } |
| 311 | } | 322 | } |
| 312 | 323 | ||
| @@ -319,11 +330,11 @@ pub enum Align { | |||
| 319 | Right, | 330 | Right, |
| 320 | } | 331 | } |
| 321 | 332 | ||
| 322 | impl From<Align> for bool { | 333 | impl From<Align> for vals::Align { |
| 323 | fn from(variant: Align) -> Self { | 334 | fn from(variant: Align) -> Self { |
| 324 | match variant { | 335 | match variant { |
| 325 | Align::Left => false, | 336 | Align::Left => vals::Align::LEFT, |
| 326 | Align::Right => true, | 337 | Align::Right => vals::Align::RIGHT, |
| 327 | } | 338 | } |
| 328 | } | 339 | } |
| 329 | } | 340 | } |
| @@ -337,11 +348,11 @@ pub enum Format { | |||
| 337 | Aligned, | 348 | Aligned, |
| 338 | } | 349 | } |
| 339 | 350 | ||
| 340 | impl From<Format> for bool { | 351 | impl From<Format> for vals::Format { |
| 341 | fn from(variant: Format) -> Self { | 352 | fn from(variant: Format) -> Self { |
| 342 | match variant { | 353 | match variant { |
| 343 | Format::I2S => false, | 354 | Format::I2S => vals::Format::I2S, |
| 344 | Format::Aligned => true, | 355 | Format::Aligned => vals::Format::ALIGNED, |
| 345 | } | 356 | } |
| 346 | } | 357 | } |
| 347 | } | 358 | } |
| @@ -357,9 +368,9 @@ pub enum Channels { | |||
| 357 | MonoRight, | 368 | MonoRight, |
| 358 | } | 369 | } |
| 359 | 370 | ||
| 360 | impl From<Channels> for u8 { | 371 | impl From<Channels> for vals::Channels { |
| 361 | fn from(variant: Channels) -> Self { | 372 | fn from(variant: Channels) -> Self { |
| 362 | variant as _ | 373 | vals::Channels::from_bits(variant as u8) |
| 363 | } | 374 | } |
| 364 | } | 375 | } |
| 365 | 376 | ||
| @@ -506,61 +517,32 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 506 | } | 517 | } |
| 507 | 518 | ||
| 508 | fn apply_config(&self) { | 519 | fn apply_config(&self) { |
| 509 | let c = &T::regs().config; | 520 | let c = T::regs().config(); |
| 510 | match &self.master_clock { | 521 | match &self.master_clock { |
| 511 | Some(MasterClock { freq, ratio }) => { | 522 | Some(MasterClock { freq, ratio }) => { |
| 512 | c.mode.write(|w| w.mode().master()); | 523 | c.mode().write(|w| w.set_mode(vals::Mode::MASTER)); |
| 513 | c.mcken.write(|w| w.mcken().enabled()); | 524 | c.mcken().write(|w| w.set_mcken(true)); |
| 514 | c.mckfreq | 525 | c.mckfreq().write(|w| w.set_mckfreq(freq.to_register_value())); |
| 515 | .write(|w| unsafe { w.mckfreq().bits(freq.to_register_value()) }); | 526 | c.ratio().write(|w| w.set_ratio(ratio.to_register_value())); |
| 516 | c.ratio.write(|w| unsafe { w.ratio().bits(ratio.to_register_value()) }); | ||
| 517 | } | 527 | } |
| 518 | None => { | 528 | None => { |
| 519 | c.mode.write(|w| w.mode().slave()); | 529 | c.mode().write(|w| w.set_mode(vals::Mode::SLAVE)); |
| 520 | } | 530 | } |
| 521 | }; | 531 | }; |
| 522 | 532 | ||
| 523 | c.swidth | 533 | c.swidth().write(|w| w.set_swidth(self.config.sample_width.into())); |
| 524 | .write(|w| unsafe { w.swidth().bits(self.config.sample_width.into()) }); | 534 | c.align().write(|w| w.set_align(self.config.align.into())); |
| 525 | c.align.write(|w| w.align().bit(self.config.align.into())); | 535 | c.format().write(|w| w.set_format(self.config.format.into())); |
| 526 | c.format.write(|w| w.format().bit(self.config.format.into())); | 536 | c.channels().write(|w| w.set_channels(self.config.channels.into())); |
| 527 | c.channels | ||
| 528 | .write(|w| unsafe { w.channels().bits(self.config.channels.into()) }); | ||
| 529 | } | 537 | } |
| 530 | 538 | ||
| 531 | fn select_pins(&self) { | 539 | fn select_pins(&self) { |
| 532 | let psel = &T::regs().psel; | 540 | let psel = T::regs().psel(); |
| 533 | 541 | psel.mck().write_value(self.mck.psel_bits()); | |
| 534 | if let Some(mck) = &self.mck { | 542 | psel.sck().write_value(self.sck.psel_bits()); |
| 535 | psel.mck.write(|w| { | 543 | psel.lrck().write_value(self.lrck.psel_bits()); |
| 536 | unsafe { w.bits(mck.psel_bits()) }; | 544 | psel.sdin().write_value(self.sdin.psel_bits()); |
| 537 | w.connect().connected() | 545 | psel.sdout().write_value(self.sdout.psel_bits()); |
| 538 | }); | ||
| 539 | } | ||
| 540 | |||
| 541 | psel.sck.write(|w| { | ||
| 542 | unsafe { w.bits(self.sck.psel_bits()) }; | ||
| 543 | w.connect().connected() | ||
| 544 | }); | ||
| 545 | |||
| 546 | psel.lrck.write(|w| { | ||
| 547 | unsafe { w.bits(self.lrck.psel_bits()) }; | ||
| 548 | w.connect().connected() | ||
| 549 | }); | ||
| 550 | |||
| 551 | if let Some(sdin) = &self.sdin { | ||
| 552 | psel.sdin.write(|w| { | ||
| 553 | unsafe { w.bits(sdin.psel_bits()) }; | ||
| 554 | w.connect().connected() | ||
| 555 | }); | ||
| 556 | } | ||
| 557 | |||
| 558 | if let Some(sdout) = &self.sdout { | ||
| 559 | psel.sdout.write(|w| { | ||
| 560 | unsafe { w.bits(sdout.psel_bits()) }; | ||
| 561 | w.connect().connected() | ||
| 562 | }); | ||
| 563 | } | ||
| 564 | } | 546 | } |
| 565 | 547 | ||
| 566 | fn setup_interrupt(&self) { | 548 | fn setup_interrupt(&self) { |
| @@ -888,7 +870,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStr | |||
| 888 | } | 870 | } |
| 889 | 871 | ||
| 890 | /// Helper encapsulating common I2S device operations. | 872 | /// Helper encapsulating common I2S device operations. |
| 891 | struct Device<T>(&'static RegisterBlock, PhantomData<T>); | 873 | struct Device<T>(pac::i2s::I2s, PhantomData<T>); |
| 892 | 874 | ||
| 893 | impl<T: Instance> Device<T> { | 875 | impl<T: Instance> Device<T> { |
| 894 | fn new() -> Self { | 876 | fn new() -> Self { |
| @@ -898,132 +880,132 @@ impl<T: Instance> Device<T> { | |||
| 898 | #[inline(always)] | 880 | #[inline(always)] |
| 899 | pub fn enable(&self) { | 881 | pub fn enable(&self) { |
| 900 | trace!("ENABLED"); | 882 | trace!("ENABLED"); |
| 901 | self.0.enable.write(|w| w.enable().enabled()); | 883 | self.0.enable().write(|w| w.set_enable(true)); |
| 902 | } | 884 | } |
| 903 | 885 | ||
| 904 | #[inline(always)] | 886 | #[inline(always)] |
| 905 | pub fn disable(&self) { | 887 | pub fn disable(&self) { |
| 906 | trace!("DISABLED"); | 888 | trace!("DISABLED"); |
| 907 | self.0.enable.write(|w| w.enable().disabled()); | 889 | self.0.enable().write(|w| w.set_enable(false)); |
| 908 | } | 890 | } |
| 909 | 891 | ||
| 910 | #[inline(always)] | 892 | #[inline(always)] |
| 911 | fn enable_tx(&self) { | 893 | fn enable_tx(&self) { |
| 912 | trace!("TX ENABLED"); | 894 | trace!("TX ENABLED"); |
| 913 | self.0.config.txen.write(|w| w.txen().enabled()); | 895 | self.0.config().txen().write(|w| w.set_txen(true)); |
| 914 | } | 896 | } |
| 915 | 897 | ||
| 916 | #[inline(always)] | 898 | #[inline(always)] |
| 917 | fn disable_tx(&self) { | 899 | fn disable_tx(&self) { |
| 918 | trace!("TX DISABLED"); | 900 | trace!("TX DISABLED"); |
| 919 | self.0.config.txen.write(|w| w.txen().disabled()); | 901 | self.0.config().txen().write(|w| w.set_txen(false)); |
| 920 | } | 902 | } |
| 921 | 903 | ||
| 922 | #[inline(always)] | 904 | #[inline(always)] |
| 923 | fn enable_rx(&self) { | 905 | fn enable_rx(&self) { |
| 924 | trace!("RX ENABLED"); | 906 | trace!("RX ENABLED"); |
| 925 | self.0.config.rxen.write(|w| w.rxen().enabled()); | 907 | self.0.config().rxen().write(|w| w.set_rxen(true)); |
| 926 | } | 908 | } |
| 927 | 909 | ||
| 928 | #[inline(always)] | 910 | #[inline(always)] |
| 929 | fn disable_rx(&self) { | 911 | fn disable_rx(&self) { |
| 930 | trace!("RX DISABLED"); | 912 | trace!("RX DISABLED"); |
| 931 | self.0.config.rxen.write(|w| w.rxen().disabled()); | 913 | self.0.config().rxen().write(|w| w.set_rxen(false)); |
| 932 | } | 914 | } |
| 933 | 915 | ||
| 934 | #[inline(always)] | 916 | #[inline(always)] |
| 935 | fn start(&self) { | 917 | fn start(&self) { |
| 936 | trace!("START"); | 918 | trace!("START"); |
| 937 | self.0.tasks_start.write(|w| unsafe { w.bits(1) }); | 919 | self.0.tasks_start().write_value(1); |
| 938 | } | 920 | } |
| 939 | 921 | ||
| 940 | #[inline(always)] | 922 | #[inline(always)] |
| 941 | fn stop(&self) { | 923 | fn stop(&self) { |
| 942 | self.0.tasks_stop.write(|w| unsafe { w.bits(1) }); | 924 | self.0.tasks_stop().write_value(1); |
| 943 | } | 925 | } |
| 944 | 926 | ||
| 945 | #[inline(always)] | 927 | #[inline(always)] |
| 946 | fn is_stopped(&self) -> bool { | 928 | fn is_stopped(&self) -> bool { |
| 947 | self.0.events_stopped.read().bits() != 0 | 929 | self.0.events_stopped().read() != 0 |
| 948 | } | 930 | } |
| 949 | 931 | ||
| 950 | #[inline(always)] | 932 | #[inline(always)] |
| 951 | fn reset_stopped_event(&self) { | 933 | fn reset_stopped_event(&self) { |
| 952 | trace!("STOPPED EVENT: Reset"); | 934 | trace!("STOPPED EVENT: Reset"); |
| 953 | self.0.events_stopped.reset(); | 935 | self.0.events_stopped().write_value(0); |
| 954 | } | 936 | } |
| 955 | 937 | ||
| 956 | #[inline(always)] | 938 | #[inline(always)] |
| 957 | fn disable_stopped_interrupt(&self) { | 939 | fn disable_stopped_interrupt(&self) { |
| 958 | trace!("STOPPED INTERRUPT: Disabled"); | 940 | trace!("STOPPED INTERRUPT: Disabled"); |
| 959 | self.0.intenclr.write(|w| w.stopped().clear()); | 941 | self.0.intenclr().write(|w| w.set_stopped(true)); |
| 960 | } | 942 | } |
| 961 | 943 | ||
| 962 | #[inline(always)] | 944 | #[inline(always)] |
| 963 | fn enable_stopped_interrupt(&self) { | 945 | fn enable_stopped_interrupt(&self) { |
| 964 | trace!("STOPPED INTERRUPT: Enabled"); | 946 | trace!("STOPPED INTERRUPT: Enabled"); |
| 965 | self.0.intenset.write(|w| w.stopped().set()); | 947 | self.0.intenset().write(|w| w.set_stopped(true)); |
| 966 | } | 948 | } |
| 967 | 949 | ||
| 968 | #[inline(always)] | 950 | #[inline(always)] |
| 969 | fn reset_tx_ptr_event(&self) { | 951 | fn reset_tx_ptr_event(&self) { |
| 970 | trace!("TX PTR EVENT: Reset"); | 952 | trace!("TX PTR EVENT: Reset"); |
| 971 | self.0.events_txptrupd.reset(); | 953 | self.0.events_txptrupd().write_value(0); |
| 972 | } | 954 | } |
| 973 | 955 | ||
| 974 | #[inline(always)] | 956 | #[inline(always)] |
| 975 | fn reset_rx_ptr_event(&self) { | 957 | fn reset_rx_ptr_event(&self) { |
| 976 | trace!("RX PTR EVENT: Reset"); | 958 | trace!("RX PTR EVENT: Reset"); |
| 977 | self.0.events_rxptrupd.reset(); | 959 | self.0.events_rxptrupd().write_value(0); |
| 978 | } | 960 | } |
| 979 | 961 | ||
| 980 | #[inline(always)] | 962 | #[inline(always)] |
| 981 | fn disable_tx_ptr_interrupt(&self) { | 963 | fn disable_tx_ptr_interrupt(&self) { |
| 982 | trace!("TX PTR INTERRUPT: Disabled"); | 964 | trace!("TX PTR INTERRUPT: Disabled"); |
| 983 | self.0.intenclr.write(|w| w.txptrupd().clear()); | 965 | self.0.intenclr().write(|w| w.set_txptrupd(true)); |
| 984 | } | 966 | } |
| 985 | 967 | ||
| 986 | #[inline(always)] | 968 | #[inline(always)] |
| 987 | fn disable_rx_ptr_interrupt(&self) { | 969 | fn disable_rx_ptr_interrupt(&self) { |
| 988 | trace!("RX PTR INTERRUPT: Disabled"); | 970 | trace!("RX PTR INTERRUPT: Disabled"); |
| 989 | self.0.intenclr.write(|w| w.rxptrupd().clear()); | 971 | self.0.intenclr().write(|w| w.set_rxptrupd(true)); |
| 990 | } | 972 | } |
| 991 | 973 | ||
| 992 | #[inline(always)] | 974 | #[inline(always)] |
| 993 | fn enable_tx_ptr_interrupt(&self) { | 975 | fn enable_tx_ptr_interrupt(&self) { |
| 994 | trace!("TX PTR INTERRUPT: Enabled"); | 976 | trace!("TX PTR INTERRUPT: Enabled"); |
| 995 | self.0.intenset.write(|w| w.txptrupd().set()); | 977 | self.0.intenset().write(|w| w.set_txptrupd(true)); |
| 996 | } | 978 | } |
| 997 | 979 | ||
| 998 | #[inline(always)] | 980 | #[inline(always)] |
| 999 | fn enable_rx_ptr_interrupt(&self) { | 981 | fn enable_rx_ptr_interrupt(&self) { |
| 1000 | trace!("RX PTR INTERRUPT: Enabled"); | 982 | trace!("RX PTR INTERRUPT: Enabled"); |
| 1001 | self.0.intenset.write(|w| w.rxptrupd().set()); | 983 | self.0.intenset().write(|w| w.set_rxptrupd(true)); |
| 1002 | } | 984 | } |
| 1003 | 985 | ||
| 1004 | #[inline(always)] | 986 | #[inline(always)] |
| 1005 | fn is_tx_ptr_updated(&self) -> bool { | 987 | fn is_tx_ptr_updated(&self) -> bool { |
| 1006 | self.0.events_txptrupd.read().bits() != 0 | 988 | self.0.events_txptrupd().read() != 0 |
| 1007 | } | 989 | } |
| 1008 | 990 | ||
| 1009 | #[inline(always)] | 991 | #[inline(always)] |
| 1010 | fn is_rx_ptr_updated(&self) -> bool { | 992 | fn is_rx_ptr_updated(&self) -> bool { |
| 1011 | self.0.events_rxptrupd.read().bits() != 0 | 993 | self.0.events_rxptrupd().read() != 0 |
| 1012 | } | 994 | } |
| 1013 | 995 | ||
| 1014 | #[inline] | 996 | #[inline] |
| 1015 | fn update_tx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> { | 997 | fn update_tx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> { |
| 1016 | let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?; | 998 | let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?; |
| 1017 | self.0.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) }); | 999 | self.0.rxtxd().maxcnt().write(|w| w.0 = maxcnt); |
| 1018 | self.0.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr) }); | 1000 | self.0.txd().ptr().write_value(ptr); |
| 1019 | Ok(()) | 1001 | Ok(()) |
| 1020 | } | 1002 | } |
| 1021 | 1003 | ||
| 1022 | #[inline] | 1004 | #[inline] |
| 1023 | fn update_rx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> { | 1005 | fn update_rx<S>(&self, buffer_ptr: *const [S]) -> Result<(), Error> { |
| 1024 | let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?; | 1006 | let (ptr, maxcnt) = Self::validated_dma_parts(buffer_ptr)?; |
| 1025 | self.0.rxtxd.maxcnt.write(|w| unsafe { w.bits(maxcnt) }); | 1007 | self.0.rxtxd().maxcnt().write(|w| w.0 = maxcnt); |
| 1026 | self.0.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr) }); | 1008 | self.0.rxd().ptr().write_value(ptr); |
| 1027 | Ok(()) | 1009 | Ok(()) |
| 1028 | } | 1010 | } |
| 1029 | 1011 | ||
| @@ -1160,7 +1142,7 @@ impl State { | |||
| 1160 | } | 1142 | } |
| 1161 | 1143 | ||
| 1162 | pub(crate) trait SealedInstance { | 1144 | pub(crate) trait SealedInstance { |
| 1163 | fn regs() -> &'static crate::pac::i2s::RegisterBlock; | 1145 | fn regs() -> pac::i2s::I2s; |
| 1164 | fn state() -> &'static State; | 1146 | fn state() -> &'static State; |
| 1165 | } | 1147 | } |
| 1166 | 1148 | ||
| @@ -1174,8 +1156,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 1174 | macro_rules! impl_i2s { | 1156 | macro_rules! impl_i2s { |
| 1175 | ($type:ident, $pac_type:ident, $irq:ident) => { | 1157 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 1176 | impl crate::i2s::SealedInstance for peripherals::$type { | 1158 | impl crate::i2s::SealedInstance for peripherals::$type { |
| 1177 | fn regs() -> &'static crate::pac::i2s::RegisterBlock { | 1159 | fn regs() -> pac::i2s::I2s { |
| 1178 | unsafe { &*pac::$pac_type::ptr() } | 1160 | pac::$pac_type |
| 1179 | } | 1161 | } |
| 1180 | fn state() -> &'static crate::i2s::State { | 1162 | fn state() -> &'static crate::i2s::State { |
| 1181 | static STATE: crate::i2s::State = crate::i2s::State::new(); | 1163 | static STATE: crate::i2s::State = crate::i2s::State::new(); |
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index bd53664a2..03d3ca5f7 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)] | 11 | #![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)] |
| 12 | 12 | ||
| 13 | #[cfg(not(any( | 13 | #[cfg(not(any( |
| 14 | feature = "nrf51", | 14 | feature = "_nrf51", |
| 15 | feature = "nrf52805", | 15 | feature = "nrf52805", |
| 16 | feature = "nrf52810", | 16 | feature = "nrf52810", |
| 17 | feature = "nrf52811", | 17 | feature = "nrf52811", |
| @@ -68,7 +68,7 @@ pub(crate) mod util; | |||
| 68 | #[cfg(feature = "_time-driver")] | 68 | #[cfg(feature = "_time-driver")] |
| 69 | mod time_driver; | 69 | mod time_driver; |
| 70 | 70 | ||
| 71 | #[cfg(not(feature = "nrf51"))] | 71 | #[cfg(not(feature = "_nrf51"))] |
| 72 | pub mod buffered_uarte; | 72 | pub mod buffered_uarte; |
| 73 | pub mod gpio; | 73 | pub mod gpio; |
| 74 | #[cfg(feature = "gpiote")] | 74 | #[cfg(feature = "gpiote")] |
| @@ -78,7 +78,7 @@ pub mod gpiote; | |||
| 78 | #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340-app")))] | 78 | #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340-app")))] |
| 79 | pub mod radio; | 79 | pub mod radio; |
| 80 | 80 | ||
| 81 | #[cfg(not(feature = "nrf51"))] | 81 | #[cfg(not(feature = "_nrf51"))] |
| 82 | pub mod egu; | 82 | pub mod egu; |
| 83 | #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] | 83 | #[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))] |
| 84 | pub mod i2s; | 84 | pub mod i2s; |
| @@ -95,32 +95,32 @@ pub mod nvmc; | |||
| 95 | pub mod pdm; | 95 | pub mod pdm; |
| 96 | pub mod ppi; | 96 | pub mod ppi; |
| 97 | #[cfg(not(any( | 97 | #[cfg(not(any( |
| 98 | feature = "nrf51", | 98 | feature = "_nrf51", |
| 99 | feature = "nrf52805", | 99 | feature = "nrf52805", |
| 100 | feature = "nrf52820", | 100 | feature = "nrf52820", |
| 101 | feature = "_nrf5340-net" | 101 | feature = "_nrf5340-net" |
| 102 | )))] | 102 | )))] |
| 103 | pub mod pwm; | 103 | pub mod pwm; |
| 104 | #[cfg(not(any(feature = "nrf51", feature = "_nrf91", feature = "_nrf5340-net")))] | 104 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf91", feature = "_nrf5340-net")))] |
| 105 | pub mod qdec; | 105 | pub mod qdec; |
| 106 | #[cfg(any(feature = "nrf52840", feature = "_nrf5340-app"))] | 106 | #[cfg(any(feature = "nrf52840", feature = "_nrf5340-app"))] |
| 107 | pub mod qspi; | 107 | pub mod qspi; |
| 108 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 108 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 109 | pub mod rng; | 109 | pub mod rng; |
| 110 | #[cfg(not(any(feature = "nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] | 110 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] |
| 111 | pub mod saadc; | 111 | pub mod saadc; |
| 112 | #[cfg(not(feature = "nrf51"))] | 112 | #[cfg(not(feature = "_nrf51"))] |
| 113 | pub mod spim; | 113 | pub mod spim; |
| 114 | #[cfg(not(feature = "nrf51"))] | 114 | #[cfg(not(feature = "_nrf51"))] |
| 115 | pub mod spis; | 115 | pub mod spis; |
| 116 | #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))] | 116 | #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))] |
| 117 | pub mod temp; | 117 | pub mod temp; |
| 118 | pub mod timer; | 118 | pub mod timer; |
| 119 | #[cfg(not(feature = "nrf51"))] | 119 | #[cfg(not(feature = "_nrf51"))] |
| 120 | pub mod twim; | 120 | pub mod twim; |
| 121 | #[cfg(not(feature = "nrf51"))] | 121 | #[cfg(not(feature = "_nrf51"))] |
| 122 | pub mod twis; | 122 | pub mod twis; |
| 123 | #[cfg(not(feature = "nrf51"))] | 123 | #[cfg(not(feature = "_nrf51"))] |
| 124 | pub mod uarte; | 124 | pub mod uarte; |
| 125 | #[cfg(any( | 125 | #[cfg(any( |
| 126 | feature = "_nrf5340-app", | 126 | feature = "_nrf5340-app", |
| @@ -133,7 +133,7 @@ pub mod usb; | |||
| 133 | pub mod wdt; | 133 | pub mod wdt; |
| 134 | 134 | ||
| 135 | // This mod MUST go last, so that it sees all the `impl_foo!` macros | 135 | // This mod MUST go last, so that it sees all the `impl_foo!` macros |
| 136 | #[cfg_attr(feature = "nrf51", path = "chips/nrf51.rs")] | 136 | #[cfg_attr(feature = "_nrf51", path = "chips/nrf51.rs")] |
| 137 | #[cfg_attr(feature = "nrf52805", path = "chips/nrf52805.rs")] | 137 | #[cfg_attr(feature = "nrf52805", path = "chips/nrf52805.rs")] |
| 138 | #[cfg_attr(feature = "nrf52810", path = "chips/nrf52810.rs")] | 138 | #[cfg_attr(feature = "nrf52810", path = "chips/nrf52810.rs")] |
| 139 | #[cfg_attr(feature = "nrf52811", path = "chips/nrf52811.rs")] | 139 | #[cfg_attr(feature = "nrf52811", path = "chips/nrf52811.rs")] |
| @@ -216,6 +216,7 @@ pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; | |||
| 216 | pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | 216 | pub use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 217 | 217 | ||
| 218 | pub use crate::chip::interrupt; | 218 | pub use crate::chip::interrupt; |
| 219 | #[cfg(feature = "rt")] | ||
| 219 | pub use crate::pac::NVIC_PRIO_BITS; | 220 | pub use crate::pac::NVIC_PRIO_BITS; |
| 220 | 221 | ||
| 221 | pub mod config { | 222 | pub mod config { |
| @@ -405,7 +406,7 @@ mod consts { | |||
| 405 | pub const APPROTECT_DISABLED: u32 = 0x0000_005a; | 406 | pub const APPROTECT_DISABLED: u32 = 0x0000_005a; |
| 406 | } | 407 | } |
| 407 | 408 | ||
| 408 | #[cfg(not(feature = "nrf51"))] | 409 | #[cfg(not(feature = "_nrf51"))] |
| 409 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | 410 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] |
| 410 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 411 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 411 | enum WriteResult { | 412 | enum WriteResult { |
| @@ -417,12 +418,12 @@ enum WriteResult { | |||
| 417 | Failed, | 418 | Failed, |
| 418 | } | 419 | } |
| 419 | 420 | ||
| 420 | #[cfg(not(feature = "nrf51"))] | 421 | #[cfg(not(feature = "_nrf51"))] |
| 421 | unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { | 422 | unsafe fn uicr_write(address: *mut u32, value: u32) -> WriteResult { |
| 422 | uicr_write_masked(address, value, 0xFFFF_FFFF) | 423 | uicr_write_masked(address, value, 0xFFFF_FFFF) |
| 423 | } | 424 | } |
| 424 | 425 | ||
| 425 | #[cfg(not(feature = "nrf51"))] | 426 | #[cfg(not(feature = "_nrf51"))] |
| 426 | unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult { | 427 | unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteResult { |
| 427 | let curr_val = address.read_volatile(); | 428 | let curr_val = address.read_volatile(); |
| 428 | if curr_val & mask == value & mask { | 429 | if curr_val & mask == value & mask { |
| @@ -434,13 +435,13 @@ unsafe fn uicr_write_masked(address: *mut u32, value: u32, mask: u32) -> WriteRe | |||
| 434 | return WriteResult::Failed; | 435 | return WriteResult::Failed; |
| 435 | } | 436 | } |
| 436 | 437 | ||
| 437 | let nvmc = &*pac::NVMC::ptr(); | 438 | let nvmc = pac::NVMC; |
| 438 | nvmc.config.write(|w| w.wen().wen()); | 439 | nvmc.config().write(|w| w.set_wen(pac::nvmc::vals::Wen::WEN)); |
| 439 | while nvmc.ready.read().ready().is_busy() {} | 440 | while !nvmc.ready().read().ready() {} |
| 440 | address.write_volatile(value | !mask); | 441 | address.write_volatile(value | !mask); |
| 441 | while nvmc.ready.read().ready().is_busy() {} | 442 | while !nvmc.ready().read().ready() {} |
| 442 | nvmc.config.reset(); | 443 | nvmc.config().write(|_| {}); |
| 443 | while nvmc.ready.read().ready().is_busy() {} | 444 | while !nvmc.ready().read().ready() {} |
| 444 | 445 | ||
| 445 | WriteResult::Written | 446 | WriteResult::Written |
| 446 | } | 447 | } |
| @@ -459,7 +460,7 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 459 | let mut needs_reset = false; | 460 | let mut needs_reset = false; |
| 460 | 461 | ||
| 461 | // Setup debug protection. | 462 | // Setup debug protection. |
| 462 | #[cfg(not(feature = "nrf51"))] | 463 | #[cfg(not(feature = "_nrf51"))] |
| 463 | match config.debug { | 464 | match config.debug { |
| 464 | config::Debug::Allowed => { | 465 | config::Debug::Allowed => { |
| 465 | #[cfg(feature = "_nrf52")] | 466 | #[cfg(feature = "_nrf52")] |
| @@ -486,17 +487,17 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 486 | 487 | ||
| 487 | #[cfg(feature = "_nrf5340")] | 488 | #[cfg(feature = "_nrf5340")] |
| 488 | unsafe { | 489 | unsafe { |
| 489 | let p = &*pac::CTRLAP::ptr(); | 490 | let p = pac::CTRLAP; |
| 490 | 491 | ||
| 491 | let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED); | 492 | let res = uicr_write(consts::UICR_APPROTECT, consts::APPROTECT_DISABLED); |
| 492 | needs_reset |= res == WriteResult::Written; | 493 | needs_reset |= res == WriteResult::Written; |
| 493 | p.approtect.disable.write(|w| w.bits(consts::APPROTECT_DISABLED)); | 494 | p.approtect().disable().write_value(consts::APPROTECT_DISABLED); |
| 494 | 495 | ||
| 495 | #[cfg(feature = "_nrf5340-app")] | 496 | #[cfg(feature = "_nrf5340-app")] |
| 496 | { | 497 | { |
| 497 | let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_DISABLED); | 498 | let res = uicr_write(consts::UICR_SECUREAPPROTECT, consts::APPROTECT_DISABLED); |
| 498 | needs_reset |= res == WriteResult::Written; | 499 | needs_reset |= res == WriteResult::Written; |
| 499 | p.secureapprotect.disable.write(|w| w.bits(consts::APPROTECT_DISABLED)); | 500 | p.secureapprotect().disable().write_value(consts::APPROTECT_DISABLED); |
| 500 | } | 501 | } |
| 501 | } | 502 | } |
| 502 | 503 | ||
| @@ -576,85 +577,79 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 576 | cortex_m::peripheral::SCB::sys_reset(); | 577 | cortex_m::peripheral::SCB::sys_reset(); |
| 577 | } | 578 | } |
| 578 | 579 | ||
| 579 | let r = unsafe { &*pac::CLOCK::ptr() }; | 580 | let r = pac::CLOCK; |
| 580 | 581 | ||
| 581 | // Start HFCLK. | 582 | // Start HFCLK. |
| 582 | match config.hfclk_source { | 583 | match config.hfclk_source { |
| 583 | config::HfclkSource::Internal => {} | 584 | config::HfclkSource::Internal => {} |
| 584 | config::HfclkSource::ExternalXtal => { | 585 | config::HfclkSource::ExternalXtal => { |
| 585 | // Datasheet says this is likely to take 0.36ms | 586 | // Datasheet says this is likely to take 0.36ms |
| 586 | r.events_hfclkstarted.write(|w| unsafe { w.bits(0) }); | 587 | r.events_hfclkstarted().write_value(0); |
| 587 | r.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 588 | r.tasks_hfclkstart().write_value(1); |
| 588 | while r.events_hfclkstarted.read().bits() == 0 {} | 589 | while r.events_hfclkstarted().read() == 0 {} |
| 589 | } | 590 | } |
| 590 | } | 591 | } |
| 591 | 592 | ||
| 592 | // Configure LFCLK. | 593 | // Configure LFCLK. |
| 593 | #[cfg(not(any(feature = "nrf51", feature = "_nrf5340", feature = "_nrf91")))] | 594 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf5340", feature = "_nrf91")))] |
| 594 | match config.lfclk_source { | 595 | match config.lfclk_source { |
| 595 | config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()), | 596 | config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::RC)), |
| 596 | config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()), | 597 | config::LfclkSource::Synthesized => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::SYNTH)), |
| 597 | 598 | config::LfclkSource::ExternalXtal => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::XTAL)), | |
| 598 | config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().xtal()), | 599 | config::LfclkSource::ExternalLowSwing => r.lfclksrc().write(|w| { |
| 599 | 600 | w.set_src(pac::clock::vals::Lfclksrc::XTAL); | |
| 600 | config::LfclkSource::ExternalLowSwing => r.lfclksrc.write(|w| { | 601 | w.set_external(true); |
| 601 | w.src().xtal(); | 602 | w.set_bypass(false); |
| 602 | w.external().enabled(); | ||
| 603 | w.bypass().disabled(); | ||
| 604 | w | ||
| 605 | }), | 603 | }), |
| 606 | config::LfclkSource::ExternalFullSwing => r.lfclksrc.write(|w| { | 604 | config::LfclkSource::ExternalFullSwing => r.lfclksrc().write(|w| { |
| 607 | w.src().xtal(); | 605 | w.set_src(pac::clock::vals::Lfclksrc::XTAL); |
| 608 | w.external().enabled(); | 606 | w.set_external(true); |
| 609 | w.bypass().enabled(); | 607 | w.set_bypass(true); |
| 610 | w | ||
| 611 | }), | 608 | }), |
| 612 | } | 609 | } |
| 613 | #[cfg(feature = "_nrf91")] | 610 | #[cfg(feature = "_nrf91")] |
| 614 | match config.lfclk_source { | 611 | match config.lfclk_source { |
| 615 | config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().lfrc()), | 612 | config::LfclkSource::InternalRC => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFRC)), |
| 616 | config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().lfxo()), | 613 | config::LfclkSource::ExternalXtal => r.lfclksrc().write(|w| w.set_src(pac::clock::vals::Lfclksrc::LFXO)), |
| 617 | } | 614 | } |
| 618 | 615 | ||
| 619 | // Start LFCLK. | 616 | // Start LFCLK. |
| 620 | // Datasheet says this could take 100us from synth source | 617 | // Datasheet says this could take 100us from synth source |
| 621 | // 600us from rc source, 0.25s from an external source. | 618 | // 600us from rc source, 0.25s from an external source. |
| 622 | r.events_lfclkstarted.write(|w| unsafe { w.bits(0) }); | 619 | r.events_lfclkstarted().write_value(0); |
| 623 | r.tasks_lfclkstart.write(|w| unsafe { w.bits(1) }); | 620 | r.tasks_lfclkstart().write_value(1); |
| 624 | while r.events_lfclkstarted.read().bits() == 0 {} | 621 | while r.events_lfclkstarted().read() == 0 {} |
| 625 | 622 | ||
| 626 | #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))] | 623 | #[cfg(not(any(feature = "_nrf5340", feature = "_nrf91")))] |
| 627 | { | 624 | { |
| 628 | // Setup DCDCs. | 625 | // Setup DCDCs. |
| 629 | let pwr = unsafe { &*pac::POWER::ptr() }; | ||
| 630 | #[cfg(feature = "nrf52840")] | 626 | #[cfg(feature = "nrf52840")] |
| 631 | if config.dcdc.reg0 { | 627 | if config.dcdc.reg0 { |
| 632 | pwr.dcdcen0.write(|w| w.dcdcen().set_bit()); | 628 | pac::POWER.dcdcen0().write(|w| w.set_dcdcen(true)); |
| 633 | } | 629 | } |
| 634 | if config.dcdc.reg1 { | 630 | if config.dcdc.reg1 { |
| 635 | pwr.dcdcen.write(|w| w.dcdcen().set_bit()); | 631 | pac::POWER.dcdcen().write(|w| w.set_dcdcen(true)); |
| 636 | } | 632 | } |
| 637 | } | 633 | } |
| 638 | #[cfg(feature = "_nrf91")] | 634 | #[cfg(feature = "_nrf91")] |
| 639 | { | 635 | { |
| 640 | // Setup DCDC. | 636 | // Setup DCDC. |
| 641 | let reg = unsafe { &*pac::REGULATORS::ptr() }; | ||
| 642 | if config.dcdc.regmain { | 637 | if config.dcdc.regmain { |
| 643 | reg.dcdcen.write(|w| w.dcdcen().set_bit()); | 638 | pac::REGULATORS.dcdcen().write(|w| w.set_dcdcen(true)); |
| 644 | } | 639 | } |
| 645 | } | 640 | } |
| 646 | #[cfg(feature = "_nrf5340-app")] | 641 | #[cfg(feature = "_nrf5340-app")] |
| 647 | { | 642 | { |
| 648 | // Setup DCDC. | 643 | // Setup DCDC. |
| 649 | let reg = unsafe { &*pac::REGULATORS::ptr() }; | 644 | let reg = pac::REGULATORS; |
| 650 | if config.dcdc.regh { | 645 | if config.dcdc.regh { |
| 651 | reg.vregh.dcdcen.write(|w| w.dcdcen().set_bit()); | 646 | reg.vregh().dcdcen().write(|w| w.set_dcdcen(true)); |
| 652 | } | 647 | } |
| 653 | if config.dcdc.regmain { | 648 | if config.dcdc.regmain { |
| 654 | reg.vregmain.dcdcen.write(|w| w.dcdcen().set_bit()); | 649 | reg.vregmain().dcdcen().write(|w| w.set_dcdcen(true)); |
| 655 | } | 650 | } |
| 656 | if config.dcdc.regradio { | 651 | if config.dcdc.regradio { |
| 657 | reg.vregradio.dcdcen.write(|w| w.dcdcen().set_bit()); | 652 | reg.vregradio().dcdcen().write(|w| w.set_dcdcen(true)); |
| 658 | } | 653 | } |
| 659 | } | 654 | } |
| 660 | 655 | ||
| @@ -668,9 +663,10 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 668 | 663 | ||
| 669 | // Disable UARTE (enabled by default for some reason) | 664 | // Disable UARTE (enabled by default for some reason) |
| 670 | #[cfg(feature = "_nrf91")] | 665 | #[cfg(feature = "_nrf91")] |
| 671 | unsafe { | 666 | { |
| 672 | (*pac::UARTE0::ptr()).enable.write(|w| w.enable().disabled()); | 667 | use pac::uarte::vals::Enable; |
| 673 | (*pac::UARTE1::ptr()).enable.write(|w| w.enable().disabled()); | 668 | pac::UARTE0.enable().write(|w| w.set_enable(Enable::DISABLED)); |
| 669 | pac::UARTE1.enable().write(|w| w.set_enable(Enable::DISABLED)); | ||
| 674 | } | 670 | } |
| 675 | 671 | ||
| 676 | peripherals | 672 | peripherals |
diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs index 9b17e7da0..6973b4847 100644 --- a/embassy-nrf/src/nvmc.rs +++ b/embassy-nrf/src/nvmc.rs | |||
| @@ -7,6 +7,7 @@ use embedded_storage::nor_flash::{ | |||
| 7 | ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, | 7 | ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash, |
| 8 | }; | 8 | }; |
| 9 | 9 | ||
| 10 | use crate::pac::nvmc::vals; | ||
| 10 | use crate::peripherals::NVMC; | 11 | use crate::peripherals::NVMC; |
| 11 | use crate::{pac, Peripheral}; | 12 | use crate::{pac, Peripheral}; |
| 12 | 13 | ||
| @@ -51,13 +52,13 @@ impl<'d> Nvmc<'d> { | |||
| 51 | Self { _p } | 52 | Self { _p } |
| 52 | } | 53 | } |
| 53 | 54 | ||
| 54 | fn regs() -> &'static pac::nvmc::RegisterBlock { | 55 | fn regs() -> pac::nvmc::Nvmc { |
| 55 | unsafe { &*pac::NVMC::ptr() } | 56 | pac::NVMC |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | fn wait_ready(&mut self) { | 59 | fn wait_ready(&mut self) { |
| 59 | let p = Self::regs(); | 60 | let p = Self::regs(); |
| 60 | while p.ready.read().ready().is_busy() {} | 61 | while !p.ready().read().ready() {} |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 63 | #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] | 64 | #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] |
| @@ -68,12 +69,12 @@ impl<'d> Nvmc<'d> { | |||
| 68 | #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] | 69 | #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] |
| 69 | fn wait_ready_write(&mut self) { | 70 | fn wait_ready_write(&mut self) { |
| 70 | let p = Self::regs(); | 71 | let p = Self::regs(); |
| 71 | while p.readynext.read().readynext().is_busy() {} | 72 | while !p.readynext().read().readynext() {} |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] | 75 | #[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))] |
| 75 | fn erase_page(&mut self, page_addr: u32) { | 76 | fn erase_page(&mut self, page_addr: u32) { |
| 76 | Self::regs().erasepage().write(|w| unsafe { w.bits(page_addr) }); | 77 | Self::regs().erasepage().write_value(page_addr); |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] | 80 | #[cfg(any(feature = "_nrf91", feature = "_nrf5340"))] |
| @@ -86,23 +87,23 @@ impl<'d> Nvmc<'d> { | |||
| 86 | 87 | ||
| 87 | fn enable_erase(&self) { | 88 | fn enable_erase(&self) { |
| 88 | #[cfg(not(feature = "_ns"))] | 89 | #[cfg(not(feature = "_ns"))] |
| 89 | Self::regs().config.write(|w| w.wen().een()); | 90 | Self::regs().config().write(|w| w.set_wen(vals::Wen::EEN)); |
| 90 | #[cfg(feature = "_ns")] | 91 | #[cfg(feature = "_ns")] |
| 91 | Self::regs().configns.write(|w| w.wen().een()); | 92 | Self::regs().configns().write(|w| w.set_wen(vals::ConfignsWen::EEN)); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | fn enable_read(&self) { | 95 | fn enable_read(&self) { |
| 95 | #[cfg(not(feature = "_ns"))] | 96 | #[cfg(not(feature = "_ns"))] |
| 96 | Self::regs().config.write(|w| w.wen().ren()); | 97 | Self::regs().config().write(|w| w.set_wen(vals::Wen::REN)); |
| 97 | #[cfg(feature = "_ns")] | 98 | #[cfg(feature = "_ns")] |
| 98 | Self::regs().configns.write(|w| w.wen().ren()); | 99 | Self::regs().configns().write(|w| w.set_wen(vals::ConfignsWen::REN)); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | fn enable_write(&self) { | 102 | fn enable_write(&self) { |
| 102 | #[cfg(not(feature = "_ns"))] | 103 | #[cfg(not(feature = "_ns"))] |
| 103 | Self::regs().config.write(|w| w.wen().wen()); | 104 | Self::regs().config().write(|w| w.set_wen(vals::Wen::WEN)); |
| 104 | #[cfg(feature = "_ns")] | 105 | #[cfg(feature = "_ns")] |
| 105 | Self::regs().configns.write(|w| w.wen().wen()); | 106 | Self::regs().configns().write(|w| w.set_wen(vals::ConfignsWen::WEN)); |
| 106 | } | 107 | } |
| 107 | } | 108 | } |
| 108 | 109 | ||
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index 5160fe3c4..483d1a644 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs | |||
| @@ -13,18 +13,19 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 13 | use fixed::types::I7F1; | 13 | use fixed::types::I7F1; |
| 14 | 14 | ||
| 15 | use crate::chip::EASY_DMA_SIZE; | 15 | use crate::chip::EASY_DMA_SIZE; |
| 16 | use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin}; | 16 | use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin, DISCONNECTED}; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::pdm::mode::{EDGE_A, OPERATION_A}; | 18 | use crate::pac::gpio::vals as gpiovals; |
| 19 | pub use crate::pac::pdm::pdmclkctrl::FREQ_A as Frequency; | 19 | use crate::pac::pdm::vals; |
| 20 | pub use crate::pac::pdm::vals::Freq as Frequency; | ||
| 20 | #[cfg(any( | 21 | #[cfg(any( |
| 21 | feature = "nrf52840", | 22 | feature = "nrf52840", |
| 22 | feature = "nrf52833", | 23 | feature = "nrf52833", |
| 23 | feature = "_nrf5340-app", | 24 | feature = "_nrf5340-app", |
| 24 | feature = "_nrf91", | 25 | feature = "_nrf91", |
| 25 | ))] | 26 | ))] |
| 26 | pub use crate::pac::pdm::ratio::RATIO_A as Ratio; | 27 | pub use crate::pac::pdm::vals::Ratio; |
| 27 | use crate::{interrupt, Peripheral}; | 28 | use crate::{interrupt, pac, Peripheral}; |
| 28 | 29 | ||
| 29 | /// Interrupt handler | 30 | /// Interrupt handler |
| 30 | pub struct InterruptHandler<T: Instance> { | 31 | pub struct InterruptHandler<T: Instance> { |
| @@ -35,16 +36,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 35 | unsafe fn on_interrupt() { | 36 | unsafe fn on_interrupt() { |
| 36 | let r = T::regs(); | 37 | let r = T::regs(); |
| 37 | 38 | ||
| 38 | if r.events_end.read().bits() != 0 { | 39 | if r.events_end().read() != 0 { |
| 39 | r.intenclr.write(|w| w.end().clear()); | 40 | r.intenclr().write(|w| w.set_end(true)); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | if r.events_started.read().bits() != 0 { | 43 | if r.events_started().read() != 0 { |
| 43 | r.intenclr.write(|w| w.started().clear()); | 44 | r.intenclr().write(|w| w.set_started(true)); |
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | if r.events_stopped.read().bits() != 0 { | 47 | if r.events_stopped().read() != 0 { |
| 47 | r.intenclr.write(|w| w.stopped().clear()); | 48 | r.intenclr().write(|w| w.set_stopped(true)); |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | T::state().waker.wake(); | 51 | T::state().waker.wake(); |
| @@ -109,50 +110,47 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 109 | let r = T::regs(); | 110 | let r = T::regs(); |
| 110 | 111 | ||
| 111 | // setup gpio pins | 112 | // setup gpio pins |
| 112 | din.conf().write(|w| w.input().set_bit()); | 113 | din.conf().write(|w| w.set_input(gpiovals::Input::CONNECT)); |
| 113 | r.psel.din.write(|w| unsafe { w.bits(din.psel_bits()) }); | 114 | r.psel().din().write_value(din.psel_bits()); |
| 114 | clk.set_low(); | 115 | clk.set_low(); |
| 115 | clk.conf().write(|w| w.dir().output()); | 116 | clk.conf().write(|w| w.set_dir(gpiovals::Dir::OUTPUT)); |
| 116 | r.psel.clk.write(|w| unsafe { w.bits(clk.psel_bits()) }); | 117 | r.psel().clk().write_value(clk.psel_bits()); |
| 117 | 118 | ||
| 118 | // configure | 119 | // configure |
| 119 | r.pdmclkctrl.write(|w| w.freq().variant(config.frequency)); | 120 | r.pdmclkctrl().write(|w| w.set_freq(config.frequency)); |
| 120 | #[cfg(any( | 121 | #[cfg(any( |
| 121 | feature = "nrf52840", | 122 | feature = "nrf52840", |
| 122 | feature = "nrf52833", | 123 | feature = "nrf52833", |
| 123 | feature = "_nrf5340-app", | 124 | feature = "_nrf5340-app", |
| 124 | feature = "_nrf91", | 125 | feature = "_nrf91", |
| 125 | ))] | 126 | ))] |
| 126 | r.ratio.write(|w| w.ratio().variant(config.ratio)); | 127 | r.ratio().write(|w| w.set_ratio(config.ratio)); |
| 127 | r.mode.write(|w| { | 128 | r.mode().write(|w| { |
| 128 | w.operation().variant(config.operation_mode.into()); | 129 | w.set_operation(config.operation_mode.into()); |
| 129 | w.edge().variant(config.edge.into()); | 130 | w.set_edge(config.edge.into()); |
| 130 | w | ||
| 131 | }); | 131 | }); |
| 132 | 132 | ||
| 133 | Self::_set_gain(r, config.gain_left, config.gain_right); | 133 | Self::_set_gain(r, config.gain_left, config.gain_right); |
| 134 | 134 | ||
| 135 | // Disable all events interrupts | 135 | // Disable all events interrupts |
| 136 | r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); | 136 | r.intenclr().write(|w| w.0 = 0x003F_FFFF); |
| 137 | 137 | ||
| 138 | // IRQ | 138 | // IRQ |
| 139 | T::Interrupt::unpend(); | 139 | T::Interrupt::unpend(); |
| 140 | unsafe { T::Interrupt::enable() }; | 140 | unsafe { T::Interrupt::enable() }; |
| 141 | 141 | ||
| 142 | r.enable.write(|w| w.enable().set_bit()); | 142 | r.enable().write(|w| w.set_enable(true)); |
| 143 | 143 | ||
| 144 | Self { _peri: pdm } | 144 | Self { _peri: pdm } |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | fn _set_gain(r: &crate::pac::pdm::RegisterBlock, gain_left: I7F1, gain_right: I7F1) { | 147 | fn _set_gain(r: pac::pdm::Pdm, gain_left: I7F1, gain_right: I7F1) { |
| 148 | let gain_to_bits = |gain: I7F1| -> u8 { | 148 | let gain_to_bits = |gain: I7F1| -> vals::Gain { |
| 149 | let gain = gain.saturating_add(I7F1::from_bits(0x28)).to_bits().clamp(0, 0x50); | 149 | let gain: i8 = gain.saturating_add(I7F1::from_bits(0x28)).to_bits().clamp(0, 0x50); |
| 150 | unsafe { core::mem::transmute(gain) } | 150 | vals::Gain::from_bits(gain as u8) |
| 151 | }; | 151 | }; |
| 152 | let gain_left = gain_to_bits(gain_left); | 152 | r.gainl().write(|w| w.set_gainl(gain_to_bits(gain_left))); |
| 153 | let gain_right = gain_to_bits(gain_right); | 153 | r.gainr().write(|w| w.set_gainr(gain_to_bits(gain_right))); |
| 154 | r.gainl.write(|w| unsafe { w.gainl().bits(gain_left) }); | ||
| 155 | r.gainr.write(|w| unsafe { w.gainr().bits(gain_right) }); | ||
| 156 | } | 154 | } |
| 157 | 155 | ||
| 158 | /// Adjust the gain of the PDM microphone on the fly | 156 | /// Adjust the gain of the PDM microphone on the fly |
| @@ -166,21 +164,17 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 166 | let r = T::regs(); | 164 | let r = T::regs(); |
| 167 | 165 | ||
| 168 | // start dummy sampling because microphone needs some setup time | 166 | // start dummy sampling because microphone needs some setup time |
| 169 | r.sample | 167 | r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); |
| 170 | .ptr | 168 | r.sample().maxcnt().write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); |
| 171 | .write(|w| unsafe { w.sampleptr().bits(DUMMY_BUFFER.as_ptr() as u32) }); | 169 | |
| 172 | r.sample | 170 | r.tasks_start().write_value(1); |
| 173 | .maxcnt | ||
| 174 | .write(|w| unsafe { w.buffsize().bits(DUMMY_BUFFER.len() as _) }); | ||
| 175 | |||
| 176 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | ||
| 177 | } | 171 | } |
| 178 | 172 | ||
| 179 | /// Stop sampling microphone data inta a dummy buffer | 173 | /// Stop sampling microphone data inta a dummy buffer |
| 180 | pub async fn stop(&mut self) { | 174 | pub async fn stop(&mut self) { |
| 181 | let r = T::regs(); | 175 | let r = T::regs(); |
| 182 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 176 | r.tasks_stop().write_value(1); |
| 183 | r.events_started.reset(); | 177 | r.events_started().write_value(0); |
| 184 | } | 178 | } |
| 185 | 179 | ||
| 186 | /// Sample data into the given buffer | 180 | /// Sample data into the given buffer |
| @@ -194,41 +188,33 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 194 | 188 | ||
| 195 | let r = T::regs(); | 189 | let r = T::regs(); |
| 196 | 190 | ||
| 197 | if r.events_started.read().bits() == 0 { | 191 | if r.events_started().read() == 0 { |
| 198 | return Err(Error::NotRunning); | 192 | return Err(Error::NotRunning); |
| 199 | } | 193 | } |
| 200 | 194 | ||
| 201 | let drop = OnDrop::new(move || { | 195 | let drop = OnDrop::new(move || { |
| 202 | r.intenclr.write(|w| w.end().clear()); | 196 | r.intenclr().write(|w| w.set_end(true)); |
| 203 | r.events_stopped.reset(); | 197 | r.events_stopped().write_value(0); |
| 204 | 198 | ||
| 205 | // reset to dummy buffer | 199 | // reset to dummy buffer |
| 206 | r.sample | 200 | r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); |
| 207 | .ptr | 201 | r.sample().maxcnt().write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); |
| 208 | .write(|w| unsafe { w.sampleptr().bits(DUMMY_BUFFER.as_ptr() as u32) }); | 202 | |
| 209 | r.sample | 203 | while r.events_stopped().read() == 0 {} |
| 210 | .maxcnt | ||
| 211 | .write(|w| unsafe { w.buffsize().bits(DUMMY_BUFFER.len() as _) }); | ||
| 212 | |||
| 213 | while r.events_stopped.read().bits() == 0 {} | ||
| 214 | }); | 204 | }); |
| 215 | 205 | ||
| 216 | // setup user buffer | 206 | // setup user buffer |
| 217 | let ptr = buffer.as_ptr(); | 207 | let ptr = buffer.as_ptr(); |
| 218 | let len = buffer.len(); | 208 | let len = buffer.len(); |
| 219 | r.sample.ptr.write(|w| unsafe { w.sampleptr().bits(ptr as u32) }); | 209 | r.sample().ptr().write_value(ptr as u32); |
| 220 | r.sample.maxcnt.write(|w| unsafe { w.buffsize().bits(len as _) }); | 210 | r.sample().maxcnt().write(|w| w.set_buffsize(len as _)); |
| 221 | 211 | ||
| 222 | // wait till the current sample is finished and the user buffer sample is started | 212 | // wait till the current sample is finished and the user buffer sample is started |
| 223 | Self::wait_for_sample().await; | 213 | Self::wait_for_sample().await; |
| 224 | 214 | ||
| 225 | // reset the buffer back to the dummy buffer | 215 | // reset the buffer back to the dummy buffer |
| 226 | r.sample | 216 | r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); |
| 227 | .ptr | 217 | r.sample().maxcnt().write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); |
| 228 | .write(|w| unsafe { w.sampleptr().bits(DUMMY_BUFFER.as_ptr() as u32) }); | ||
| 229 | r.sample | ||
| 230 | .maxcnt | ||
| 231 | .write(|w| unsafe { w.buffsize().bits(DUMMY_BUFFER.len() as _) }); | ||
| 232 | 218 | ||
| 233 | // wait till the user buffer is sampled | 219 | // wait till the user buffer is sampled |
| 234 | Self::wait_for_sample().await; | 220 | Self::wait_for_sample().await; |
| @@ -241,14 +227,14 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 241 | async fn wait_for_sample() { | 227 | async fn wait_for_sample() { |
| 242 | let r = T::regs(); | 228 | let r = T::regs(); |
| 243 | 229 | ||
| 244 | r.events_end.reset(); | 230 | r.events_end().write_value(0); |
| 245 | r.intenset.write(|w| w.end().set()); | 231 | r.intenset().write(|w| w.set_end(true)); |
| 246 | 232 | ||
| 247 | compiler_fence(Ordering::SeqCst); | 233 | compiler_fence(Ordering::SeqCst); |
| 248 | 234 | ||
| 249 | poll_fn(|cx| { | 235 | poll_fn(|cx| { |
| 250 | T::state().waker.register(cx.waker()); | 236 | T::state().waker.register(cx.waker()); |
| 251 | if r.events_end.read().bits() != 0 { | 237 | if r.events_end().read() != 0 { |
| 252 | return Poll::Ready(()); | 238 | return Poll::Ready(()); |
| 253 | } | 239 | } |
| 254 | Poll::Pending | 240 | Poll::Pending |
| @@ -279,40 +265,37 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 279 | { | 265 | { |
| 280 | let r = T::regs(); | 266 | let r = T::regs(); |
| 281 | 267 | ||
| 282 | if r.events_started.read().bits() != 0 { | 268 | if r.events_started().read() != 0 { |
| 283 | return Err(Error::AlreadyRunning); | 269 | return Err(Error::AlreadyRunning); |
| 284 | } | 270 | } |
| 285 | 271 | ||
| 286 | r.sample | 272 | r.sample().ptr().write_value(bufs[0].as_mut_ptr() as u32); |
| 287 | .ptr | 273 | r.sample().maxcnt().write(|w| w.set_buffsize(N as _)); |
| 288 | .write(|w| unsafe { w.sampleptr().bits(bufs[0].as_mut_ptr() as u32) }); | ||
| 289 | r.sample.maxcnt.write(|w| unsafe { w.buffsize().bits(N as _) }); | ||
| 290 | 274 | ||
| 291 | // Reset and enable the events | 275 | // Reset and enable the events |
| 292 | r.events_end.reset(); | 276 | r.events_end().write_value(0); |
| 293 | r.events_started.reset(); | 277 | r.events_started().write_value(0); |
| 294 | r.events_stopped.reset(); | 278 | r.events_stopped().write_value(0); |
| 295 | r.intenset.write(|w| { | 279 | r.intenset().write(|w| { |
| 296 | w.end().set(); | 280 | w.set_end(true); |
| 297 | w.started().set(); | 281 | w.set_started(true); |
| 298 | w.stopped().set(); | 282 | w.set_stopped(true); |
| 299 | w | ||
| 300 | }); | 283 | }); |
| 301 | 284 | ||
| 302 | // Don't reorder the start event before the previous writes. Hopefully self | 285 | // Don't reorder the start event before the previous writes. Hopefully self |
| 303 | // wouldn't happen anyway | 286 | // wouldn't happen anyway |
| 304 | compiler_fence(Ordering::SeqCst); | 287 | compiler_fence(Ordering::SeqCst); |
| 305 | 288 | ||
| 306 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 289 | r.tasks_start().write_value(1); |
| 307 | 290 | ||
| 308 | let mut current_buffer = 0; | 291 | let mut current_buffer = 0; |
| 309 | 292 | ||
| 310 | let mut done = false; | 293 | let mut done = false; |
| 311 | 294 | ||
| 312 | let drop = OnDrop::new(|| { | 295 | let drop = OnDrop::new(|| { |
| 313 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 296 | r.tasks_stop().write_value(1); |
| 314 | // N.B. It would be better if this were async, but Drop only support sync code | 297 | // N.B. It would be better if this were async, but Drop only support sync code |
| 315 | while r.events_stopped.read().bits() != 0 {} | 298 | while r.events_stopped().read() != 0 {} |
| 316 | }); | 299 | }); |
| 317 | 300 | ||
| 318 | // Wait for events and complete when the sampler indicates it has had enough | 301 | // Wait for events and complete when the sampler indicates it has had enough |
| @@ -321,11 +304,11 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 321 | 304 | ||
| 322 | T::state().waker.register(cx.waker()); | 305 | T::state().waker.register(cx.waker()); |
| 323 | 306 | ||
| 324 | if r.events_end.read().bits() != 0 { | 307 | if r.events_end().read() != 0 { |
| 325 | compiler_fence(Ordering::SeqCst); | 308 | compiler_fence(Ordering::SeqCst); |
| 326 | 309 | ||
| 327 | r.events_end.reset(); | 310 | r.events_end().write_value(0); |
| 328 | r.intenset.write(|w| w.end().set()); | 311 | r.intenset().write(|w| w.set_end(true)); |
| 329 | 312 | ||
| 330 | if !done { | 313 | if !done { |
| 331 | // Discard the last buffer after the user requested a stop | 314 | // Discard the last buffer after the user requested a stop |
| @@ -333,23 +316,21 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 333 | let next_buffer = 1 - current_buffer; | 316 | let next_buffer = 1 - current_buffer; |
| 334 | current_buffer = next_buffer; | 317 | current_buffer = next_buffer; |
| 335 | } else { | 318 | } else { |
| 336 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 319 | r.tasks_stop().write_value(1); |
| 337 | done = true; | 320 | done = true; |
| 338 | }; | 321 | }; |
| 339 | }; | 322 | }; |
| 340 | } | 323 | } |
| 341 | 324 | ||
| 342 | if r.events_started.read().bits() != 0 { | 325 | if r.events_started().read() != 0 { |
| 343 | r.events_started.reset(); | 326 | r.events_started().write_value(0); |
| 344 | r.intenset.write(|w| w.started().set()); | 327 | r.intenset().write(|w| w.set_started(true)); |
| 345 | 328 | ||
| 346 | let next_buffer = 1 - current_buffer; | 329 | let next_buffer = 1 - current_buffer; |
| 347 | r.sample | 330 | r.sample().ptr().write_value(bufs[next_buffer].as_mut_ptr() as u32); |
| 348 | .ptr | ||
| 349 | .write(|w| unsafe { w.sampleptr().bits(bufs[next_buffer].as_mut_ptr() as u32) }); | ||
| 350 | } | 331 | } |
| 351 | 332 | ||
| 352 | if r.events_stopped.read().bits() != 0 { | 333 | if r.events_stopped().read() != 0 { |
| 353 | return Poll::Ready(()); | 334 | return Poll::Ready(()); |
| 354 | } | 335 | } |
| 355 | 336 | ||
| @@ -411,11 +392,11 @@ pub enum OperationMode { | |||
| 411 | Stereo, | 392 | Stereo, |
| 412 | } | 393 | } |
| 413 | 394 | ||
| 414 | impl From<OperationMode> for OPERATION_A { | 395 | impl From<OperationMode> for vals::Operation { |
| 415 | fn from(mode: OperationMode) -> Self { | 396 | fn from(mode: OperationMode) -> Self { |
| 416 | match mode { | 397 | match mode { |
| 417 | OperationMode::Mono => OPERATION_A::MONO, | 398 | OperationMode::Mono => vals::Operation::MONO, |
| 418 | OperationMode::Stereo => OPERATION_A::STEREO, | 399 | OperationMode::Stereo => vals::Operation::STEREO, |
| 419 | } | 400 | } |
| 420 | } | 401 | } |
| 421 | } | 402 | } |
| @@ -429,11 +410,11 @@ pub enum Edge { | |||
| 429 | LeftFalling, | 410 | LeftFalling, |
| 430 | } | 411 | } |
| 431 | 412 | ||
| 432 | impl From<Edge> for EDGE_A { | 413 | impl From<Edge> for vals::Edge { |
| 433 | fn from(edge: Edge) -> Self { | 414 | fn from(edge: Edge) -> Self { |
| 434 | match edge { | 415 | match edge { |
| 435 | Edge::LeftRising => EDGE_A::LEFT_RISING, | 416 | Edge::LeftRising => vals::Edge::LEFT_RISING, |
| 436 | Edge::LeftFalling => EDGE_A::LEFT_FALLING, | 417 | Edge::LeftFalling => vals::Edge::LEFT_FALLING, |
| 437 | } | 418 | } |
| 438 | } | 419 | } |
| 439 | } | 420 | } |
| @@ -442,12 +423,12 @@ impl<'d, T: Instance> Drop for Pdm<'d, T> { | |||
| 442 | fn drop(&mut self) { | 423 | fn drop(&mut self) { |
| 443 | let r = T::regs(); | 424 | let r = T::regs(); |
| 444 | 425 | ||
| 445 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 426 | r.tasks_stop().write_value(1); |
| 446 | 427 | ||
| 447 | r.enable.write(|w| w.enable().disabled()); | 428 | r.enable().write(|w| w.set_enable(false)); |
| 448 | 429 | ||
| 449 | r.psel.din.reset(); | 430 | r.psel().din().write_value(DISCONNECTED); |
| 450 | r.psel.clk.reset(); | 431 | r.psel().clk().write_value(DISCONNECTED); |
| 451 | } | 432 | } |
| 452 | } | 433 | } |
| 453 | 434 | ||
| @@ -465,7 +446,7 @@ impl State { | |||
| 465 | } | 446 | } |
| 466 | 447 | ||
| 467 | pub(crate) trait SealedInstance { | 448 | pub(crate) trait SealedInstance { |
| 468 | fn regs() -> &'static crate::pac::pdm::RegisterBlock; | 449 | fn regs() -> crate::pac::pdm::Pdm; |
| 469 | fn state() -> &'static State; | 450 | fn state() -> &'static State; |
| 470 | } | 451 | } |
| 471 | 452 | ||
| @@ -479,8 +460,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 479 | macro_rules! impl_pdm { | 460 | macro_rules! impl_pdm { |
| 480 | ($type:ident, $pac_type:ident, $irq:ident) => { | 461 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 481 | impl crate::pdm::SealedInstance for peripherals::$type { | 462 | impl crate::pdm::SealedInstance for peripherals::$type { |
| 482 | fn regs() -> &'static crate::pac::pdm::RegisterBlock { | 463 | fn regs() -> crate::pac::pdm::Pdm { |
| 483 | unsafe { &*pac::$pac_type::ptr() } | 464 | pac::$pac_type |
| 484 | } | 465 | } |
| 485 | fn state() -> &'static crate::pdm::State { | 466 | fn state() -> &'static crate::pdm::State { |
| 486 | static STATE: crate::pdm::State = crate::pdm::State::new(); | 467 | static STATE: crate::pdm::State = crate::pdm::State::new(); |
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 0bc7f821e..3c7b96df7 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs | |||
| @@ -6,8 +6,8 @@ use crate::{pac, Peripheral}; | |||
| 6 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | 6 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; |
| 7 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | 7 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; |
| 8 | 8 | ||
| 9 | pub(crate) fn regs() -> &'static pac::dppic::RegisterBlock { | 9 | pub(crate) fn regs() -> pac::dppic::Dppic { |
| 10 | unsafe { &*pac::DPPIC::ptr() } | 10 | pac::DPPIC |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { | 13 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { |
| @@ -57,13 +57,13 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, | |||
| 57 | /// Enables the channel. | 57 | /// Enables the channel. |
| 58 | pub fn enable(&mut self) { | 58 | pub fn enable(&mut self) { |
| 59 | let n = self.ch.number(); | 59 | let n = self.ch.number(); |
| 60 | regs().chenset.write(|w| unsafe { w.bits(1 << n) }); | 60 | regs().chenset().write(|w| w.0 = 1 << n); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | /// Disables the channel. | 63 | /// Disables the channel. |
| 64 | pub fn disable(&mut self) { | 64 | pub fn disable(&mut self) { |
| 65 | let n = self.ch.number(); | 65 | let n = self.ch.number(); |
| 66 | regs().chenclr.write(|w| unsafe { w.bits(1 << n) }); | 66 | regs().chenclr().write(|w| w.0 = 1 << n); |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | 69 | ||
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 13f7dcc83..325e4ce00 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs | |||
| @@ -20,6 +20,7 @@ use core::ptr::NonNull; | |||
| 20 | 20 | ||
| 21 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; | 21 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 22 | 22 | ||
| 23 | use crate::pac::common::{Reg, RW, W}; | ||
| 23 | use crate::{peripherals, Peripheral}; | 24 | use crate::{peripherals, Peripheral}; |
| 24 | 25 | ||
| 25 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] | 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] |
| @@ -50,7 +51,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 50 | 51 | ||
| 51 | let r = regs(); | 52 | let r = regs(); |
| 52 | let n = g.number(); | 53 | let n = g.number(); |
| 53 | r.chg[n].write(|w| unsafe { w.bits(0) }); | 54 | r.chg(n).write(|_| ()); |
| 54 | 55 | ||
| 55 | Self { g } | 56 | Self { g } |
| 56 | } | 57 | } |
| @@ -65,7 +66,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 65 | let r = regs(); | 66 | let r = regs(); |
| 66 | let ng = self.g.number(); | 67 | let ng = self.g.number(); |
| 67 | let nc = ch.ch.number(); | 68 | let nc = ch.ch.number(); |
| 68 | r.chg[ng].modify(|r, w| unsafe { w.bits(r.bits() | 1 << nc) }); | 69 | r.chg(ng).modify(|w| w.set_ch(nc, true)); |
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | /// Remove a PPI channel from this group. | 72 | /// Remove a PPI channel from this group. |
| @@ -78,19 +79,19 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 78 | let r = regs(); | 79 | let r = regs(); |
| 79 | let ng = self.g.number(); | 80 | let ng = self.g.number(); |
| 80 | let nc = ch.ch.number(); | 81 | let nc = ch.ch.number(); |
| 81 | r.chg[ng].modify(|r, w| unsafe { w.bits(r.bits() & !(1 << nc)) }); | 82 | r.chg(ng).modify(|w| w.set_ch(nc, false)); |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | /// Enable all the channels in this group. | 85 | /// Enable all the channels in this group. |
| 85 | pub fn enable_all(&mut self) { | 86 | pub fn enable_all(&mut self) { |
| 86 | let n = self.g.number(); | 87 | let n = self.g.number(); |
| 87 | regs().tasks_chg[n].en.write(|w| unsafe { w.bits(1) }); | 88 | regs().tasks_chg(n).en().write_value(1); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | /// Disable all the channels in this group. | 91 | /// Disable all the channels in this group. |
| 91 | pub fn disable_all(&mut self) { | 92 | pub fn disable_all(&mut self) { |
| 92 | let n = self.g.number(); | 93 | let n = self.g.number(); |
| 93 | regs().tasks_chg[n].dis.write(|w| unsafe { w.bits(1) }); | 94 | regs().tasks_chg(n).dis().write_value(1); |
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | /// Get a reference to the "enable all" task. | 97 | /// Get a reference to the "enable all" task. |
| @@ -98,7 +99,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 98 | /// When triggered, it will enable all the channels in this group. | 99 | /// When triggered, it will enable all the channels in this group. |
| 99 | pub fn task_enable_all(&self) -> Task<'d> { | 100 | pub fn task_enable_all(&self) -> Task<'d> { |
| 100 | let n = self.g.number(); | 101 | let n = self.g.number(); |
| 101 | Task::from_reg(®s().tasks_chg[n].en) | 102 | Task::from_reg(regs().tasks_chg(n).en()) |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | /// Get a reference to the "disable all" task. | 105 | /// Get a reference to the "disable all" task. |
| @@ -106,7 +107,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 106 | /// When triggered, it will disable all the channels in this group. | 107 | /// When triggered, it will disable all the channels in this group. |
| 107 | pub fn task_disable_all(&self) -> Task<'d> { | 108 | pub fn task_disable_all(&self) -> Task<'d> { |
| 108 | let n = self.g.number(); | 109 | let n = self.g.number(); |
| 109 | Task::from_reg(®s().tasks_chg[n].dis) | 110 | Task::from_reg(regs().tasks_chg(n).dis()) |
| 110 | } | 111 | } |
| 111 | } | 112 | } |
| 112 | 113 | ||
| @@ -114,7 +115,7 @@ impl<'d, G: Group> Drop for PpiGroup<'d, G> { | |||
| 114 | fn drop(&mut self) { | 115 | fn drop(&mut self) { |
| 115 | let r = regs(); | 116 | let r = regs(); |
| 116 | let n = self.g.number(); | 117 | let n = self.g.number(); |
| 117 | r.chg[n].write(|w| unsafe { w.bits(0) }); | 118 | r.chg(n).write(|_| ()); |
| 118 | } | 119 | } |
| 119 | } | 120 | } |
| 120 | 121 | ||
| @@ -143,11 +144,8 @@ impl<'d> Task<'d> { | |||
| 143 | unsafe { self.0.as_ptr().write_volatile(1) }; | 144 | unsafe { self.0.as_ptr().write_volatile(1) }; |
| 144 | } | 145 | } |
| 145 | 146 | ||
| 146 | pub(crate) fn from_reg<T>(reg: &T) -> Self { | 147 | pub(crate) fn from_reg(reg: Reg<u32, W>) -> Self { |
| 147 | Self( | 148 | Self(unsafe { NonNull::new_unchecked(reg.as_ptr()) }, PhantomData) |
| 148 | unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }, | ||
| 149 | PhantomData, | ||
| 150 | ) | ||
| 151 | } | 149 | } |
| 152 | 150 | ||
| 153 | /// Address of subscription register for this task. | 151 | /// Address of subscription register for this task. |
| @@ -178,11 +176,8 @@ impl<'d> Event<'d> { | |||
| 178 | Self(ptr, PhantomData) | 176 | Self(ptr, PhantomData) |
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | pub(crate) fn from_reg<T>(reg: &'d T) -> Self { | 179 | pub(crate) fn from_reg(reg: Reg<u32, RW>) -> Self { |
| 182 | Self( | 180 | Self(unsafe { NonNull::new_unchecked(reg.as_ptr()) }, PhantomData) |
| 183 | unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) }, | ||
| 184 | PhantomData, | ||
| 185 | ) | ||
| 186 | } | 181 | } |
| 187 | 182 | ||
| 188 | /// Describes whether this Event is currently in a triggered state. | 183 | /// Describes whether this Event is currently in a triggered state. |
| @@ -284,7 +279,7 @@ impl ConfigurableChannel for AnyConfigurableChannel { | |||
| 284 | } | 279 | } |
| 285 | } | 280 | } |
| 286 | 281 | ||
| 287 | #[cfg(not(feature = "nrf51"))] | 282 | #[cfg(not(feature = "_nrf51"))] |
| 288 | macro_rules! impl_ppi_channel { | 283 | macro_rules! impl_ppi_channel { |
| 289 | ($type:ident, $number:expr) => { | 284 | ($type:ident, $number:expr) => { |
| 290 | impl crate::ppi::SealedChannel for peripherals::$type {} | 285 | impl crate::ppi::SealedChannel for peripherals::$type {} |
| @@ -366,7 +361,7 @@ impl_group!(PPI_GROUP0, 0); | |||
| 366 | impl_group!(PPI_GROUP1, 1); | 361 | impl_group!(PPI_GROUP1, 1); |
| 367 | impl_group!(PPI_GROUP2, 2); | 362 | impl_group!(PPI_GROUP2, 2); |
| 368 | impl_group!(PPI_GROUP3, 3); | 363 | impl_group!(PPI_GROUP3, 3); |
| 369 | #[cfg(not(feature = "nrf51"))] | 364 | #[cfg(not(feature = "_nrf51"))] |
| 370 | impl_group!(PPI_GROUP4, 4); | 365 | impl_group!(PPI_GROUP4, 4); |
| 371 | #[cfg(not(feature = "nrf51"))] | 366 | #[cfg(not(feature = "_nrf51"))] |
| 372 | impl_group!(PPI_GROUP5, 5); | 367 | impl_group!(PPI_GROUP5, 5); |
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index 8ff52ece3..a1beb9dcd 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs | |||
| @@ -14,11 +14,11 @@ impl<'d> Event<'d> { | |||
| 14 | } | 14 | } |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | pub(crate) fn regs() -> &'static pac::ppi::RegisterBlock { | 17 | pub(crate) fn regs() -> pac::ppi::Ppi { |
| 18 | unsafe { &*pac::PPI::ptr() } | 18 | pac::PPI |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | #[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task | 21 | #[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task |
| 22 | impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { | 22 | impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { |
| 23 | /// Configure PPI channel to trigger `task`. | 23 | /// Configure PPI channel to trigger `task`. |
| 24 | pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self { | 24 | pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self { |
| @@ -26,7 +26,7 @@ impl<'d, C: super::StaticChannel> Ppi<'d, C, 0, 1> { | |||
| 26 | 26 | ||
| 27 | let r = regs(); | 27 | let r = regs(); |
| 28 | let n = ch.number(); | 28 | let n = ch.number(); |
| 29 | r.fork[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); | 29 | r.fork(n).tep().write_value(task.reg_val()); |
| 30 | 30 | ||
| 31 | Self { ch } | 31 | Self { ch } |
| 32 | } | 32 | } |
| @@ -39,14 +39,14 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { | |||
| 39 | 39 | ||
| 40 | let r = regs(); | 40 | let r = regs(); |
| 41 | let n = ch.number(); | 41 | let n = ch.number(); |
| 42 | r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); | 42 | r.ch(n).eep().write_value(event.reg_val()); |
| 43 | r.ch[n].tep.write(|w| unsafe { w.bits(task.reg_val()) }); | 43 | r.ch(n).tep().write_value(task.reg_val()); |
| 44 | 44 | ||
| 45 | Self { ch } | 45 | Self { ch } |
| 46 | } | 46 | } |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | #[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task | 49 | #[cfg(not(feature = "_nrf51"))] // Not for nrf51 because of the fork task |
| 50 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { | 50 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { |
| 51 | /// Configure PPI channel to trigger both `task1` and `task2` on `event`. | 51 | /// Configure PPI channel to trigger both `task1` and `task2` on `event`. |
| 52 | pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { | 52 | pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event<'d>, task1: Task<'d>, task2: Task<'d>) -> Self { |
| @@ -54,9 +54,9 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> { | |||
| 54 | 54 | ||
| 55 | let r = regs(); | 55 | let r = regs(); |
| 56 | let n = ch.number(); | 56 | let n = ch.number(); |
| 57 | r.ch[n].eep.write(|w| unsafe { w.bits(event.reg_val()) }); | 57 | r.ch(n).eep().write_value(event.reg_val()); |
| 58 | r.ch[n].tep.write(|w| unsafe { w.bits(task1.reg_val()) }); | 58 | r.ch(n).tep().write_value(task1.reg_val()); |
| 59 | r.fork[n].tep.write(|w| unsafe { w.bits(task2.reg_val()) }); | 59 | r.fork(n).tep().write_value(task2.reg_val()); |
| 60 | 60 | ||
| 61 | Self { ch } | 61 | Self { ch } |
| 62 | } | 62 | } |
| @@ -66,13 +66,13 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, | |||
| 66 | /// Enables the channel. | 66 | /// Enables the channel. |
| 67 | pub fn enable(&mut self) { | 67 | pub fn enable(&mut self) { |
| 68 | let n = self.ch.number(); | 68 | let n = self.ch.number(); |
| 69 | regs().chenset.write(|w| unsafe { w.bits(1 << n) }); | 69 | regs().chenset().write(|w| w.set_ch(n, true)); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | /// Disables the channel. | 72 | /// Disables the channel. |
| 73 | pub fn disable(&mut self) { | 73 | pub fn disable(&mut self) { |
| 74 | let n = self.ch.number(); | 74 | let n = self.ch.number(); |
| 75 | regs().chenclr.write(|w| unsafe { w.bits(1 << n) }); | 75 | regs().chenclr().write(|w| w.set_ch(n, true)); |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| 78 | 78 | ||
| @@ -82,9 +82,9 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Drop for | |||
| 82 | 82 | ||
| 83 | let r = regs(); | 83 | let r = regs(); |
| 84 | let n = self.ch.number(); | 84 | let n = self.ch.number(); |
| 85 | r.ch[n].eep.write(|w| unsafe { w.bits(0) }); | 85 | r.ch(n).eep().write_value(0); |
| 86 | r.ch[n].tep.write(|w| unsafe { w.bits(0) }); | 86 | r.ch(n).tep().write_value(0); |
| 87 | #[cfg(not(feature = "nrf51"))] | 87 | #[cfg(not(feature = "_nrf51"))] |
| 88 | r.fork[n].tep.write(|w| unsafe { w.bits(0) }); | 88 | r.fork(n).tep().write_value(0); |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 8e8f166d7..c8f1e0b09 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -6,7 +6,9 @@ use core::sync::atomic::{compiler_fence, Ordering}; | |||
| 6 | 6 | ||
| 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | 8 | ||
| 9 | use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _}; | 9 | use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; |
| 10 | use crate::pac::gpio::vals as gpiovals; | ||
| 11 | use crate::pac::pwm::vals; | ||
| 10 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| 11 | use crate::util::slice_in_ram_or; | 13 | use crate::util::slice_in_ram_or; |
| 12 | use crate::{interrupt, pac, Peripheral}; | 14 | use crate::{interrupt, pac, Peripheral}; |
| @@ -128,52 +130,61 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 128 | 130 | ||
| 129 | if let Some(pin) = &ch0 { | 131 | if let Some(pin) = &ch0 { |
| 130 | pin.set_low(); | 132 | pin.set_low(); |
| 131 | pin.conf() | 133 | pin.conf().write(|w| { |
| 132 | .write(|w| w.dir().output().drive().variant(convert_drive(config.ch0_drive))); | 134 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 135 | w.set_drive(convert_drive(config.ch0_drive)); | ||
| 136 | }); | ||
| 133 | } | 137 | } |
| 134 | if let Some(pin) = &ch1 { | 138 | if let Some(pin) = &ch1 { |
| 135 | pin.set_low(); | 139 | pin.set_low(); |
| 136 | pin.conf() | 140 | pin.conf().write(|w| { |
| 137 | .write(|w| w.dir().output().drive().variant(convert_drive(config.ch1_drive))); | 141 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 142 | w.set_drive(convert_drive(config.ch1_drive)); | ||
| 143 | }); | ||
| 138 | } | 144 | } |
| 139 | if let Some(pin) = &ch2 { | 145 | if let Some(pin) = &ch2 { |
| 140 | pin.set_low(); | 146 | pin.set_low(); |
| 141 | pin.conf() | 147 | pin.conf().write(|w| { |
| 142 | .write(|w| w.dir().output().drive().variant(convert_drive(config.ch2_drive))); | 148 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 149 | w.set_drive(convert_drive(config.ch2_drive)); | ||
| 150 | }); | ||
| 143 | } | 151 | } |
| 144 | if let Some(pin) = &ch3 { | 152 | if let Some(pin) = &ch3 { |
| 145 | pin.set_low(); | 153 | pin.set_low(); |
| 146 | pin.conf() | 154 | pin.conf().write(|w| { |
| 147 | .write(|w| w.dir().output().drive().variant(convert_drive(config.ch3_drive))); | 155 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 156 | w.set_drive(convert_drive(config.ch3_drive)); | ||
| 157 | }); | ||
| 148 | } | 158 | } |
| 149 | 159 | ||
| 150 | r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); | 160 | r.psel().out(0).write_value(ch0.psel_bits()); |
| 151 | r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); | 161 | r.psel().out(1).write_value(ch1.psel_bits()); |
| 152 | r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); | 162 | r.psel().out(2).write_value(ch2.psel_bits()); |
| 153 | r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); | 163 | r.psel().out(3).write_value(ch3.psel_bits()); |
| 154 | 164 | ||
| 155 | // Disable all interrupts | 165 | // Disable all interrupts |
| 156 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 166 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 157 | r.shorts.reset(); | 167 | r.shorts().write(|_| ()); |
| 158 | r.events_stopped.reset(); | 168 | r.events_stopped().write_value(0); |
| 159 | r.events_loopsdone.reset(); | 169 | r.events_loopsdone().write_value(0); |
| 160 | r.events_seqend[0].reset(); | 170 | r.events_seqend(0).write_value(0); |
| 161 | r.events_seqend[1].reset(); | 171 | r.events_seqend(1).write_value(0); |
| 162 | r.events_pwmperiodend.reset(); | 172 | r.events_pwmperiodend().write_value(0); |
| 163 | r.events_seqstarted[0].reset(); | 173 | r.events_seqstarted(0).write_value(0); |
| 164 | r.events_seqstarted[1].reset(); | 174 | r.events_seqstarted(1).write_value(0); |
| 165 | 175 | ||
| 166 | r.decoder.write(|w| { | 176 | r.decoder().write(|w| { |
| 167 | w.load().bits(config.sequence_load as u8); | 177 | w.set_load(vals::Load::from_bits(config.sequence_load as u8)); |
| 168 | w.mode().refresh_count() | 178 | w.set_mode(vals::Mode::REFRESH_COUNT); |
| 169 | }); | 179 | }); |
| 170 | 180 | ||
| 171 | r.mode.write(|w| match config.counter_mode { | 181 | r.mode().write(|w| match config.counter_mode { |
| 172 | CounterMode::UpAndDown => w.updown().up_and_down(), | 182 | CounterMode::UpAndDown => w.set_updown(vals::Updown::UP_AND_DOWN), |
| 173 | CounterMode::Up => w.updown().up(), | 183 | CounterMode::Up => w.set_updown(vals::Updown::UP), |
| 174 | }); | 184 | }); |
| 175 | r.prescaler.write(|w| w.prescaler().bits(config.prescaler as u8)); | 185 | r.prescaler() |
| 176 | r.countertop.write(|w| unsafe { w.countertop().bits(config.max_duty) }); | 186 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(config.prescaler as u8))); |
| 187 | r.countertop().write(|w| w.set_countertop(config.max_duty)); | ||
| 177 | 188 | ||
| 178 | Ok(Self { | 189 | Ok(Self { |
| 179 | _peri: _pwm, | 190 | _peri: _pwm, |
| @@ -189,7 +200,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 189 | pub fn event_stopped(&self) -> Event<'d> { | 200 | pub fn event_stopped(&self) -> Event<'d> { |
| 190 | let r = T::regs(); | 201 | let r = T::regs(); |
| 191 | 202 | ||
| 192 | Event::from_reg(&r.events_stopped) | 203 | Event::from_reg(r.events_stopped()) |
| 193 | } | 204 | } |
| 194 | 205 | ||
| 195 | /// Returns reference to `LoopsDone` event endpoint for PPI. | 206 | /// Returns reference to `LoopsDone` event endpoint for PPI. |
| @@ -197,7 +208,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 197 | pub fn event_loops_done(&self) -> Event<'d> { | 208 | pub fn event_loops_done(&self) -> Event<'d> { |
| 198 | let r = T::regs(); | 209 | let r = T::regs(); |
| 199 | 210 | ||
| 200 | Event::from_reg(&r.events_loopsdone) | 211 | Event::from_reg(r.events_loopsdone()) |
| 201 | } | 212 | } |
| 202 | 213 | ||
| 203 | /// Returns reference to `PwmPeriodEnd` event endpoint for PPI. | 214 | /// Returns reference to `PwmPeriodEnd` event endpoint for PPI. |
| @@ -205,7 +216,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 205 | pub fn event_pwm_period_end(&self) -> Event<'d> { | 216 | pub fn event_pwm_period_end(&self) -> Event<'d> { |
| 206 | let r = T::regs(); | 217 | let r = T::regs(); |
| 207 | 218 | ||
| 208 | Event::from_reg(&r.events_pwmperiodend) | 219 | Event::from_reg(r.events_pwmperiodend()) |
| 209 | } | 220 | } |
| 210 | 221 | ||
| 211 | /// Returns reference to `Seq0 End` event endpoint for PPI. | 222 | /// Returns reference to `Seq0 End` event endpoint for PPI. |
| @@ -213,7 +224,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 213 | pub fn event_seq_end(&self) -> Event<'d> { | 224 | pub fn event_seq_end(&self) -> Event<'d> { |
| 214 | let r = T::regs(); | 225 | let r = T::regs(); |
| 215 | 226 | ||
| 216 | Event::from_reg(&r.events_seqend[0]) | 227 | Event::from_reg(r.events_seqend(0)) |
| 217 | } | 228 | } |
| 218 | 229 | ||
| 219 | /// Returns reference to `Seq1 End` event endpoint for PPI. | 230 | /// Returns reference to `Seq1 End` event endpoint for PPI. |
| @@ -221,7 +232,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 221 | pub fn event_seq1_end(&self) -> Event<'d> { | 232 | pub fn event_seq1_end(&self) -> Event<'d> { |
| 222 | let r = T::regs(); | 233 | let r = T::regs(); |
| 223 | 234 | ||
| 224 | Event::from_reg(&r.events_seqend[1]) | 235 | Event::from_reg(r.events_seqend(1)) |
| 225 | } | 236 | } |
| 226 | 237 | ||
| 227 | /// Returns reference to `Seq0 Started` event endpoint for PPI. | 238 | /// Returns reference to `Seq0 Started` event endpoint for PPI. |
| @@ -229,7 +240,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 229 | pub fn event_seq0_started(&self) -> Event<'d> { | 240 | pub fn event_seq0_started(&self) -> Event<'d> { |
| 230 | let r = T::regs(); | 241 | let r = T::regs(); |
| 231 | 242 | ||
| 232 | Event::from_reg(&r.events_seqstarted[0]) | 243 | Event::from_reg(r.events_seqstarted(0)) |
| 233 | } | 244 | } |
| 234 | 245 | ||
| 235 | /// Returns reference to `Seq1 Started` event endpoint for PPI. | 246 | /// Returns reference to `Seq1 Started` event endpoint for PPI. |
| @@ -237,7 +248,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 237 | pub fn event_seq1_started(&self) -> Event<'d> { | 248 | pub fn event_seq1_started(&self) -> Event<'d> { |
| 238 | let r = T::regs(); | 249 | let r = T::regs(); |
| 239 | 250 | ||
| 240 | Event::from_reg(&r.events_seqstarted[1]) | 251 | Event::from_reg(r.events_seqstarted(1)) |
| 241 | } | 252 | } |
| 242 | 253 | ||
| 243 | /// Returns reference to `Seq0 Start` task endpoint for PPI. | 254 | /// Returns reference to `Seq0 Start` task endpoint for PPI. |
| @@ -248,7 +259,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 248 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { | 259 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { |
| 249 | let r = T::regs(); | 260 | let r = T::regs(); |
| 250 | 261 | ||
| 251 | Task::from_reg(&r.tasks_seqstart[0]) | 262 | Task::from_reg(r.tasks_seqstart(0)) |
| 252 | } | 263 | } |
| 253 | 264 | ||
| 254 | /// Returns reference to `Seq1 Started` task endpoint for PPI. | 265 | /// Returns reference to `Seq1 Started` task endpoint for PPI. |
| @@ -259,7 +270,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 259 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { | 270 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { |
| 260 | let r = T::regs(); | 271 | let r = T::regs(); |
| 261 | 272 | ||
| 262 | Task::from_reg(&r.tasks_seqstart[1]) | 273 | Task::from_reg(r.tasks_seqstart(1)) |
| 263 | } | 274 | } |
| 264 | 275 | ||
| 265 | /// Returns reference to `NextStep` task endpoint for PPI. | 276 | /// Returns reference to `NextStep` task endpoint for PPI. |
| @@ -270,7 +281,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 270 | pub unsafe fn task_next_step(&self) -> Task<'d> { | 281 | pub unsafe fn task_next_step(&self) -> Task<'d> { |
| 271 | let r = T::regs(); | 282 | let r = T::regs(); |
| 272 | 283 | ||
| 273 | Task::from_reg(&r.tasks_nextstep) | 284 | Task::from_reg(r.tasks_nextstep()) |
| 274 | } | 285 | } |
| 275 | 286 | ||
| 276 | /// Returns reference to `Stop` task endpoint for PPI. | 287 | /// Returns reference to `Stop` task endpoint for PPI. |
| @@ -281,7 +292,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 281 | pub unsafe fn task_stop(&self) -> Task<'d> { | 292 | pub unsafe fn task_stop(&self) -> Task<'d> { |
| 282 | let r = T::regs(); | 293 | let r = T::regs(); |
| 283 | 294 | ||
| 284 | Task::from_reg(&r.tasks_stop) | 295 | Task::from_reg(r.tasks_stop()) |
| 285 | } | 296 | } |
| 286 | } | 297 | } |
| 287 | 298 | ||
| @@ -291,23 +302,23 @@ impl<'a, T: Instance> Drop for SequencePwm<'a, T> { | |||
| 291 | 302 | ||
| 292 | if let Some(pin) = &self.ch0 { | 303 | if let Some(pin) = &self.ch0 { |
| 293 | pin.set_low(); | 304 | pin.set_low(); |
| 294 | pin.conf().reset(); | 305 | pin.conf().write(|_| ()); |
| 295 | r.psel.out[0].reset(); | 306 | r.psel().out(0).write_value(DISCONNECTED); |
| 296 | } | 307 | } |
| 297 | if let Some(pin) = &self.ch1 { | 308 | if let Some(pin) = &self.ch1 { |
| 298 | pin.set_low(); | 309 | pin.set_low(); |
| 299 | pin.conf().reset(); | 310 | pin.conf().write(|_| ()); |
| 300 | r.psel.out[1].reset(); | 311 | r.psel().out(1).write_value(DISCONNECTED); |
| 301 | } | 312 | } |
| 302 | if let Some(pin) = &self.ch2 { | 313 | if let Some(pin) = &self.ch2 { |
| 303 | pin.set_low(); | 314 | pin.set_low(); |
| 304 | pin.conf().reset(); | 315 | pin.conf().write(|_| ()); |
| 305 | r.psel.out[2].reset(); | 316 | r.psel().out(2).write_value(DISCONNECTED); |
| 306 | } | 317 | } |
| 307 | if let Some(pin) = &self.ch3 { | 318 | if let Some(pin) = &self.ch3 { |
| 308 | pin.set_low(); | 319 | pin.set_low(); |
| 309 | pin.conf().reset(); | 320 | pin.conf().write(|_| ()); |
| 310 | r.psel.out[3].reset(); | 321 | r.psel().out(3).write_value(DISCONNECTED); |
| 311 | } | 322 | } |
| 312 | } | 323 | } |
| 313 | } | 324 | } |
| @@ -463,21 +474,17 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 463 | 474 | ||
| 464 | let r = T::regs(); | 475 | let r = T::regs(); |
| 465 | 476 | ||
| 466 | r.seq0.refresh.write(|w| unsafe { w.bits(sequence0.config.refresh) }); | 477 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); |
| 467 | r.seq0.enddelay.write(|w| unsafe { w.bits(sequence0.config.end_delay) }); | 478 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); |
| 468 | r.seq0.ptr.write(|w| unsafe { w.bits(sequence0.words.as_ptr() as u32) }); | 479 | r.seq(0).ptr().write_value(sequence0.words.as_ptr() as u32); |
| 469 | r.seq0.cnt.write(|w| unsafe { w.bits(sequence0.words.len() as u32) }); | 480 | r.seq(0).cnt().write(|w| w.0 = sequence0.words.len() as u32); |
| 470 | 481 | ||
| 471 | r.seq1.refresh.write(|w| unsafe { w.bits(alt_sequence.config.refresh) }); | 482 | r.seq(1).refresh().write(|w| w.0 = alt_sequence.config.refresh); |
| 472 | r.seq1 | 483 | r.seq(1).enddelay().write(|w| w.0 = alt_sequence.config.end_delay); |
| 473 | .enddelay | 484 | r.seq(1).ptr().write_value(alt_sequence.words.as_ptr() as u32); |
| 474 | .write(|w| unsafe { w.bits(alt_sequence.config.end_delay) }); | 485 | r.seq(1).cnt().write(|w| w.0 = alt_sequence.words.len() as u32); |
| 475 | r.seq1 | ||
| 476 | .ptr | ||
| 477 | .write(|w| unsafe { w.bits(alt_sequence.words.as_ptr() as u32) }); | ||
| 478 | r.seq1.cnt.write(|w| unsafe { w.bits(alt_sequence.words.len() as u32) }); | ||
| 479 | 486 | ||
| 480 | r.enable.write(|w| w.enable().enabled()); | 487 | r.enable().write(|w| w.set_enable(true)); |
| 481 | 488 | ||
| 482 | // defensive before seqstart | 489 | // defensive before seqstart |
| 483 | compiler_fence(Ordering::SeqCst); | 490 | compiler_fence(Ordering::SeqCst); |
| @@ -486,18 +493,17 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 486 | 493 | ||
| 487 | match times { | 494 | match times { |
| 488 | // just the one time, no loop count | 495 | // just the one time, no loop count |
| 489 | SequenceMode::Loop(n) => { | 496 | SequenceMode::Loop(_) => { |
| 490 | r.loop_.write(|w| unsafe { w.cnt().bits(n) }); | 497 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::DISABLED)); |
| 491 | } | 498 | } |
| 492 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again | 499 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again |
| 493 | SequenceMode::Infinite => { | 500 | SequenceMode::Infinite => { |
| 494 | r.loop_.write(|w| unsafe { w.cnt().bits(0x1) }); | 501 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::from_bits(1))); |
| 495 | r.shorts.write(|w| w.loopsdone_seqstart0().enabled()); | 502 | r.shorts().write(|w| w.set_loopsdone_seqstart0(true)); |
| 496 | } | 503 | } |
| 497 | } | 504 | } |
| 498 | 505 | ||
| 499 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 506 | r.tasks_seqstart(seqstart_index).write_value(1); |
| 500 | r.tasks_seqstart[seqstart_index].write(|w| unsafe { w.bits(0x01) }); | ||
| 501 | 507 | ||
| 502 | Ok(()) | 508 | Ok(()) |
| 503 | } | 509 | } |
| @@ -509,14 +515,12 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 509 | pub fn stop(&self) { | 515 | pub fn stop(&self) { |
| 510 | let r = T::regs(); | 516 | let r = T::regs(); |
| 511 | 517 | ||
| 512 | r.shorts.reset(); | 518 | r.shorts().write(|_| ()); |
| 513 | 519 | ||
| 514 | compiler_fence(Ordering::SeqCst); | 520 | compiler_fence(Ordering::SeqCst); |
| 515 | 521 | ||
| 516 | // tasks_stop() doesn't exist in all svds so write its bit instead | 522 | r.tasks_stop().write_value(1); |
| 517 | r.tasks_stop.write(|w| unsafe { w.bits(0x01) }); | 523 | r.enable().write(|w| w.set_enable(false)); |
| 518 | |||
| 519 | r.enable.write(|w| w.enable().disabled()); | ||
| 520 | } | 524 | } |
| 521 | } | 525 | } |
| 522 | 526 | ||
| @@ -672,30 +676,14 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 672 | 676 | ||
| 673 | let r = T::regs(); | 677 | let r = T::regs(); |
| 674 | 678 | ||
| 675 | if let Some(pin) = &ch0 { | 679 | for (i, ch) in [&ch0, &ch1, &ch2, &ch3].into_iter().enumerate() { |
| 676 | pin.set_low(); | 680 | if let Some(pin) = ch { |
| 677 | pin.conf().write(|w| w.dir().output()); | 681 | pin.set_low(); |
| 678 | } | 682 | pin.conf().write(|w| w.set_dir(gpiovals::Dir::OUTPUT)); |
| 679 | if let Some(pin) = &ch1 { | 683 | } |
| 680 | pin.set_low(); | 684 | r.psel().out(i).write_value(ch0.psel_bits()); |
| 681 | pin.conf().write(|w| w.dir().output()); | ||
| 682 | } | ||
| 683 | if let Some(pin) = &ch2 { | ||
| 684 | pin.set_low(); | ||
| 685 | pin.conf().write(|w| w.dir().output()); | ||
| 686 | } | ||
| 687 | if let Some(pin) = &ch3 { | ||
| 688 | pin.set_low(); | ||
| 689 | pin.conf().write(|w| w.dir().output()); | ||
| 690 | } | 685 | } |
| 691 | 686 | ||
| 692 | // if NoPin provided writes disconnected (top bit 1) 0x80000000 else | ||
| 693 | // writes pin number ex 13 (0x0D) which is connected (top bit 0) | ||
| 694 | r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); | ||
| 695 | r.psel.out[1].write(|w| unsafe { w.bits(ch1.psel_bits()) }); | ||
| 696 | r.psel.out[2].write(|w| unsafe { w.bits(ch2.psel_bits()) }); | ||
| 697 | r.psel.out[3].write(|w| unsafe { w.bits(ch3.psel_bits()) }); | ||
| 698 | |||
| 699 | let pwm = Self { | 687 | let pwm = Self { |
| 700 | _peri: _pwm, | 688 | _peri: _pwm, |
| 701 | ch0, | 689 | ch0, |
| @@ -706,26 +694,25 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 706 | }; | 694 | }; |
| 707 | 695 | ||
| 708 | // Disable all interrupts | 696 | // Disable all interrupts |
| 709 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 697 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 710 | r.shorts.reset(); | 698 | r.shorts().write(|_| ()); |
| 711 | 699 | ||
| 712 | // Enable | 700 | // Enable |
| 713 | r.enable.write(|w| w.enable().enabled()); | 701 | r.enable().write(|w| w.set_enable(true)); |
| 714 | |||
| 715 | r.seq0.ptr.write(|w| unsafe { w.bits((pwm.duty).as_ptr() as u32) }); | ||
| 716 | 702 | ||
| 717 | r.seq0.cnt.write(|w| unsafe { w.bits(4) }); | 703 | r.seq(0).ptr().write_value((pwm.duty).as_ptr() as u32); |
| 718 | r.seq0.refresh.write(|w| unsafe { w.bits(0) }); | 704 | r.seq(0).cnt().write(|w| w.0 = 4); |
| 719 | r.seq0.enddelay.write(|w| unsafe { w.bits(0) }); | 705 | r.seq(0).refresh().write(|w| w.0 = 0); |
| 706 | r.seq(0).enddelay().write(|w| w.0 = 0); | ||
| 720 | 707 | ||
| 721 | r.decoder.write(|w| { | 708 | r.decoder().write(|w| { |
| 722 | w.load().individual(); | 709 | w.set_load(vals::Load::INDIVIDUAL); |
| 723 | w.mode().refresh_count() | 710 | w.set_mode(vals::Mode::REFRESH_COUNT); |
| 724 | }); | 711 | }); |
| 725 | r.mode.write(|w| w.updown().up()); | 712 | r.mode().write(|w| w.set_updown(vals::Updown::UP)); |
| 726 | r.prescaler.write(|w| w.prescaler().div_16()); | 713 | r.prescaler().write(|w| w.set_prescaler(vals::Prescaler::DIV_16)); |
| 727 | r.countertop.write(|w| unsafe { w.countertop().bits(1000) }); | 714 | r.countertop().write(|w| w.set_countertop(1000)); |
| 728 | r.loop_.write(|w| w.cnt().disabled()); | 715 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::DISABLED)); |
| 729 | 716 | ||
| 730 | pwm | 717 | pwm |
| 731 | } | 718 | } |
| @@ -734,21 +721,21 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 734 | #[inline(always)] | 721 | #[inline(always)] |
| 735 | pub fn is_enabled(&self) -> bool { | 722 | pub fn is_enabled(&self) -> bool { |
| 736 | let r = T::regs(); | 723 | let r = T::regs(); |
| 737 | r.enable.read().enable().bit_is_set() | 724 | r.enable().read().enable() |
| 738 | } | 725 | } |
| 739 | 726 | ||
| 740 | /// Enables the PWM generator. | 727 | /// Enables the PWM generator. |
| 741 | #[inline(always)] | 728 | #[inline(always)] |
| 742 | pub fn enable(&self) { | 729 | pub fn enable(&self) { |
| 743 | let r = T::regs(); | 730 | let r = T::regs(); |
| 744 | r.enable.write(|w| w.enable().enabled()); | 731 | r.enable().write(|w| w.set_enable(true)); |
| 745 | } | 732 | } |
| 746 | 733 | ||
| 747 | /// Disables the PWM generator. Does NOT clear the last duty cycle from the pin. | 734 | /// Disables the PWM generator. Does NOT clear the last duty cycle from the pin. |
| 748 | #[inline(always)] | 735 | #[inline(always)] |
| 749 | pub fn disable(&self) { | 736 | pub fn disable(&self) { |
| 750 | let r = T::regs(); | 737 | let r = T::regs(); |
| 751 | r.enable.write(|w| w.enable().disabled()); | 738 | r.enable().write(|w| w.set_enable(false)); |
| 752 | } | 739 | } |
| 753 | 740 | ||
| 754 | /// Returns the current duty of the channel | 741 | /// Returns the current duty of the channel |
| @@ -763,33 +750,35 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 763 | self.duty[channel] = duty & 0x7FFF; | 750 | self.duty[channel] = duty & 0x7FFF; |
| 764 | 751 | ||
| 765 | // reload ptr in case self was moved | 752 | // reload ptr in case self was moved |
| 766 | r.seq0.ptr.write(|w| unsafe { w.bits((self.duty).as_ptr() as u32) }); | 753 | r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); |
| 767 | 754 | ||
| 768 | // defensive before seqstart | 755 | // defensive before seqstart |
| 769 | compiler_fence(Ordering::SeqCst); | 756 | compiler_fence(Ordering::SeqCst); |
| 770 | 757 | ||
| 771 | r.events_seqend[0].reset(); | 758 | r.events_seqend(0).write_value(0); |
| 772 | 759 | ||
| 773 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 760 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 774 | r.tasks_seqstart[0].write(|w| unsafe { w.bits(1) }); | 761 | r.tasks_seqstart(0).write_value(1); |
| 775 | 762 | ||
| 776 | // defensive wait until waveform is loaded after seqstart so set_duty | 763 | // defensive wait until waveform is loaded after seqstart so set_duty |
| 777 | // can't be called again while dma is still reading | 764 | // can't be called again while dma is still reading |
| 778 | if self.is_enabled() { | 765 | if self.is_enabled() { |
| 779 | while r.events_seqend[0].read().bits() == 0 {} | 766 | while r.events_seqend(0).read() == 0 {} |
| 780 | } | 767 | } |
| 781 | } | 768 | } |
| 782 | 769 | ||
| 783 | /// Sets the PWM clock prescaler. | 770 | /// Sets the PWM clock prescaler. |
| 784 | #[inline(always)] | 771 | #[inline(always)] |
| 785 | pub fn set_prescaler(&self, div: Prescaler) { | 772 | pub fn set_prescaler(&self, div: Prescaler) { |
| 786 | T::regs().prescaler.write(|w| w.prescaler().bits(div as u8)); | 773 | T::regs() |
| 774 | .prescaler() | ||
| 775 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(div as u8))); | ||
| 787 | } | 776 | } |
| 788 | 777 | ||
| 789 | /// Gets the PWM clock prescaler. | 778 | /// Gets the PWM clock prescaler. |
| 790 | #[inline(always)] | 779 | #[inline(always)] |
| 791 | pub fn prescaler(&self) -> Prescaler { | 780 | pub fn prescaler(&self) -> Prescaler { |
| 792 | match T::regs().prescaler.read().prescaler().bits() { | 781 | match T::regs().prescaler().read().prescaler().to_bits() { |
| 793 | 0 => Prescaler::Div1, | 782 | 0 => Prescaler::Div1, |
| 794 | 1 => Prescaler::Div2, | 783 | 1 => Prescaler::Div2, |
| 795 | 2 => Prescaler::Div4, | 784 | 2 => Prescaler::Div4, |
| @@ -805,15 +794,13 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 805 | /// Sets the maximum duty cycle value. | 794 | /// Sets the maximum duty cycle value. |
| 806 | #[inline(always)] | 795 | #[inline(always)] |
| 807 | pub fn set_max_duty(&self, duty: u16) { | 796 | pub fn set_max_duty(&self, duty: u16) { |
| 808 | T::regs() | 797 | T::regs().countertop().write(|w| w.set_countertop(duty.min(32767u16))); |
| 809 | .countertop | ||
| 810 | .write(|w| unsafe { w.countertop().bits(duty.min(32767u16)) }); | ||
| 811 | } | 798 | } |
| 812 | 799 | ||
| 813 | /// Returns the maximum duty cycle value. | 800 | /// Returns the maximum duty cycle value. |
| 814 | #[inline(always)] | 801 | #[inline(always)] |
| 815 | pub fn max_duty(&self) -> u16 { | 802 | pub fn max_duty(&self) -> u16 { |
| 816 | T::regs().countertop.read().countertop().bits() | 803 | T::regs().countertop().read().countertop() |
| 817 | } | 804 | } |
| 818 | 805 | ||
| 819 | /// Sets the PWM output frequency. | 806 | /// Sets the PWM output frequency. |
| @@ -836,7 +823,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 836 | #[inline(always)] | 823 | #[inline(always)] |
| 837 | pub fn set_ch0_drive(&self, drive: OutputDrive) { | 824 | pub fn set_ch0_drive(&self, drive: OutputDrive) { |
| 838 | if let Some(pin) = &self.ch0 { | 825 | if let Some(pin) = &self.ch0 { |
| 839 | pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive))); | 826 | pin.conf().modify(|w| w.set_drive(convert_drive(drive))); |
| 840 | } | 827 | } |
| 841 | } | 828 | } |
| 842 | 829 | ||
| @@ -844,7 +831,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 844 | #[inline(always)] | 831 | #[inline(always)] |
| 845 | pub fn set_ch1_drive(&self, drive: OutputDrive) { | 832 | pub fn set_ch1_drive(&self, drive: OutputDrive) { |
| 846 | if let Some(pin) = &self.ch1 { | 833 | if let Some(pin) = &self.ch1 { |
| 847 | pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive))); | 834 | pin.conf().modify(|w| w.set_drive(convert_drive(drive))); |
| 848 | } | 835 | } |
| 849 | } | 836 | } |
| 850 | 837 | ||
| @@ -852,7 +839,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 852 | #[inline(always)] | 839 | #[inline(always)] |
| 853 | pub fn set_ch2_drive(&self, drive: OutputDrive) { | 840 | pub fn set_ch2_drive(&self, drive: OutputDrive) { |
| 854 | if let Some(pin) = &self.ch2 { | 841 | if let Some(pin) = &self.ch2 { |
| 855 | pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive))); | 842 | pin.conf().modify(|w| w.set_drive(convert_drive(drive))); |
| 856 | } | 843 | } |
| 857 | } | 844 | } |
| 858 | 845 | ||
| @@ -860,7 +847,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 860 | #[inline(always)] | 847 | #[inline(always)] |
| 861 | pub fn set_ch3_drive(&self, drive: OutputDrive) { | 848 | pub fn set_ch3_drive(&self, drive: OutputDrive) { |
| 862 | if let Some(pin) = &self.ch3 { | 849 | if let Some(pin) = &self.ch3 { |
| 863 | pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive))); | 850 | pin.conf().modify(|w| w.set_drive(convert_drive(drive))); |
| 864 | } | 851 | } |
| 865 | } | 852 | } |
| 866 | } | 853 | } |
| @@ -873,29 +860,29 @@ impl<'a, T: Instance> Drop for SimplePwm<'a, T> { | |||
| 873 | 860 | ||
| 874 | if let Some(pin) = &self.ch0 { | 861 | if let Some(pin) = &self.ch0 { |
| 875 | pin.set_low(); | 862 | pin.set_low(); |
| 876 | pin.conf().reset(); | 863 | pin.conf().write(|_| ()); |
| 877 | r.psel.out[0].reset(); | 864 | r.psel().out(0).write_value(DISCONNECTED); |
| 878 | } | 865 | } |
| 879 | if let Some(pin) = &self.ch1 { | 866 | if let Some(pin) = &self.ch1 { |
| 880 | pin.set_low(); | 867 | pin.set_low(); |
| 881 | pin.conf().reset(); | 868 | pin.conf().write(|_| ()); |
| 882 | r.psel.out[1].reset(); | 869 | r.psel().out(1).write_value(DISCONNECTED); |
| 883 | } | 870 | } |
| 884 | if let Some(pin) = &self.ch2 { | 871 | if let Some(pin) = &self.ch2 { |
| 885 | pin.set_low(); | 872 | pin.set_low(); |
| 886 | pin.conf().reset(); | 873 | pin.conf().write(|_| ()); |
| 887 | r.psel.out[2].reset(); | 874 | r.psel().out(2).write_value(DISCONNECTED); |
| 888 | } | 875 | } |
| 889 | if let Some(pin) = &self.ch3 { | 876 | if let Some(pin) = &self.ch3 { |
| 890 | pin.set_low(); | 877 | pin.set_low(); |
| 891 | pin.conf().reset(); | 878 | pin.conf().write(|_| ()); |
| 892 | r.psel.out[3].reset(); | 879 | r.psel().out(3).write_value(DISCONNECTED); |
| 893 | } | 880 | } |
| 894 | } | 881 | } |
| 895 | } | 882 | } |
| 896 | 883 | ||
| 897 | pub(crate) trait SealedInstance { | 884 | pub(crate) trait SealedInstance { |
| 898 | fn regs() -> &'static pac::pwm0::RegisterBlock; | 885 | fn regs() -> pac::pwm::Pwm; |
| 899 | } | 886 | } |
| 900 | 887 | ||
| 901 | /// PWM peripheral instance. | 888 | /// PWM peripheral instance. |
| @@ -908,8 +895,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { | |||
| 908 | macro_rules! impl_pwm { | 895 | macro_rules! impl_pwm { |
| 909 | ($type:ident, $pac_type:ident, $irq:ident) => { | 896 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 910 | impl crate::pwm::SealedInstance for peripherals::$type { | 897 | impl crate::pwm::SealedInstance for peripherals::$type { |
| 911 | fn regs() -> &'static pac::pwm0::RegisterBlock { | 898 | fn regs() -> pac::pwm::Pwm { |
| 912 | unsafe { &*pac::$pac_type::ptr() } | 899 | pac::$pac_type |
| 913 | } | 900 | } |
| 914 | } | 901 | } |
| 915 | impl crate::pwm::Instance for peripherals::$type { | 902 | impl crate::pwm::Instance for peripherals::$type { |
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs index 7409c9b1e..efd2a134c 100644 --- a/embassy-nrf/src/qdec.rs +++ b/embassy-nrf/src/qdec.rs | |||
| @@ -11,7 +11,9 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 11 | 11 | ||
| 12 | use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; | 12 | use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _}; |
| 13 | use crate::interrupt::typelevel::Interrupt; | 13 | use crate::interrupt::typelevel::Interrupt; |
| 14 | use crate::{interrupt, Peripheral}; | 14 | use crate::pac::gpio::vals as gpiovals; |
| 15 | use crate::pac::qdec::vals; | ||
| 16 | use crate::{interrupt, pac, Peripheral}; | ||
| 15 | 17 | ||
| 16 | /// Quadrature decoder driver. | 18 | /// Quadrature decoder driver. |
| 17 | pub struct Qdec<'d, T: Instance> { | 19 | pub struct Qdec<'d, T: Instance> { |
| @@ -52,7 +54,7 @@ pub struct InterruptHandler<T: Instance> { | |||
| 52 | 54 | ||
| 53 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { | 55 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { |
| 54 | unsafe fn on_interrupt() { | 56 | unsafe fn on_interrupt() { |
| 55 | T::regs().intenclr.write(|w| w.reportrdy().clear()); | 57 | T::regs().intenclr().write(|w| w.set_reportrdy(true)); |
| 56 | T::state().waker.wake(); | 58 | T::state().waker.wake(); |
| 57 | } | 59 | } |
| 58 | } | 60 | } |
| @@ -93,54 +95,59 @@ impl<'d, T: Instance> Qdec<'d, T> { | |||
| 93 | let r = T::regs(); | 95 | let r = T::regs(); |
| 94 | 96 | ||
| 95 | // Select pins. | 97 | // Select pins. |
| 96 | a.conf().write(|w| w.input().connect().pull().pullup()); | 98 | a.conf().write(|w| { |
| 97 | b.conf().write(|w| w.input().connect().pull().pullup()); | 99 | w.set_input(gpiovals::Input::CONNECT); |
| 98 | r.psel.a.write(|w| unsafe { w.bits(a.psel_bits()) }); | 100 | w.set_pull(gpiovals::Pull::PULLUP); |
| 99 | r.psel.b.write(|w| unsafe { w.bits(b.psel_bits()) }); | 101 | }); |
| 102 | b.conf().write(|w| { | ||
| 103 | w.set_input(gpiovals::Input::CONNECT); | ||
| 104 | w.set_pull(gpiovals::Pull::PULLUP); | ||
| 105 | }); | ||
| 106 | r.psel().a().write_value(a.psel_bits()); | ||
| 107 | r.psel().b().write_value(b.psel_bits()); | ||
| 100 | if let Some(led_pin) = &led { | 108 | if let Some(led_pin) = &led { |
| 101 | led_pin.conf().write(|w| w.dir().output()); | 109 | led_pin.conf().write(|w| w.set_dir(gpiovals::Dir::OUTPUT)); |
| 102 | r.psel.led.write(|w| unsafe { w.bits(led_pin.psel_bits()) }); | 110 | r.psel().led().write_value(led_pin.psel_bits()); |
| 103 | } | 111 | } |
| 104 | 112 | ||
| 105 | // Enables/disable input debounce filters | 113 | // Enables/disable input debounce filters |
| 106 | r.dbfen.write(|w| match config.debounce { | 114 | r.dbfen().write(|w| match config.debounce { |
| 107 | true => w.dbfen().enabled(), | 115 | true => w.set_dbfen(true), |
| 108 | false => w.dbfen().disabled(), | 116 | false => w.set_dbfen(false), |
| 109 | }); | 117 | }); |
| 110 | 118 | ||
| 111 | // Set LED output pin polarity | 119 | // Set LED output pin polarity |
| 112 | r.ledpol.write(|w| match config.led_polarity { | 120 | r.ledpol().write(|w| match config.led_polarity { |
| 113 | LedPolarity::ActiveHigh => w.ledpol().active_high(), | 121 | LedPolarity::ActiveHigh => w.set_ledpol(vals::Ledpol::ACTIVE_HIGH), |
| 114 | LedPolarity::ActiveLow => w.ledpol().active_low(), | 122 | LedPolarity::ActiveLow => w.set_ledpol(vals::Ledpol::ACTIVE_LOW), |
| 115 | }); | 123 | }); |
| 116 | 124 | ||
| 117 | // Set time period the LED is switched ON prior to sampling (0..511 us). | 125 | // Set time period the LED is switched ON prior to sampling (0..511 us). |
| 118 | r.ledpre | 126 | r.ledpre().write(|w| w.set_ledpre(config.led_pre_usecs.min(511))); |
| 119 | .write(|w| unsafe { w.ledpre().bits(config.led_pre_usecs.min(511)) }); | ||
| 120 | 127 | ||
| 121 | // Set sample period | 128 | // Set sample period |
| 122 | r.sampleper.write(|w| match config.period { | 129 | r.sampleper().write(|w| match config.period { |
| 123 | SamplePeriod::_128us => w.sampleper()._128us(), | 130 | SamplePeriod::_128us => w.set_sampleper(vals::Sampleper::_128US), |
| 124 | SamplePeriod::_256us => w.sampleper()._256us(), | 131 | SamplePeriod::_256us => w.set_sampleper(vals::Sampleper::_256US), |
| 125 | SamplePeriod::_512us => w.sampleper()._512us(), | 132 | SamplePeriod::_512us => w.set_sampleper(vals::Sampleper::_512US), |
| 126 | SamplePeriod::_1024us => w.sampleper()._1024us(), | 133 | SamplePeriod::_1024us => w.set_sampleper(vals::Sampleper::_1024US), |
| 127 | SamplePeriod::_2048us => w.sampleper()._2048us(), | 134 | SamplePeriod::_2048us => w.set_sampleper(vals::Sampleper::_2048US), |
| 128 | SamplePeriod::_4096us => w.sampleper()._4096us(), | 135 | SamplePeriod::_4096us => w.set_sampleper(vals::Sampleper::_4096US), |
| 129 | SamplePeriod::_8192us => w.sampleper()._8192us(), | 136 | SamplePeriod::_8192us => w.set_sampleper(vals::Sampleper::_8192US), |
| 130 | SamplePeriod::_16384us => w.sampleper()._16384us(), | 137 | SamplePeriod::_16384us => w.set_sampleper(vals::Sampleper::_16384US), |
| 131 | SamplePeriod::_32ms => w.sampleper()._32ms(), | 138 | SamplePeriod::_32ms => w.set_sampleper(vals::Sampleper::_32MS), |
| 132 | SamplePeriod::_65ms => w.sampleper()._65ms(), | 139 | SamplePeriod::_65ms => w.set_sampleper(vals::Sampleper::_65MS), |
| 133 | SamplePeriod::_131ms => w.sampleper()._131ms(), | 140 | SamplePeriod::_131ms => w.set_sampleper(vals::Sampleper::_131MS), |
| 134 | }); | 141 | }); |
| 135 | 142 | ||
| 136 | T::Interrupt::unpend(); | 143 | T::Interrupt::unpend(); |
| 137 | unsafe { T::Interrupt::enable() }; | 144 | unsafe { T::Interrupt::enable() }; |
| 138 | 145 | ||
| 139 | // Enable peripheral | 146 | // Enable peripheral |
| 140 | r.enable.write(|w| w.enable().set_bit()); | 147 | r.enable().write(|w| w.set_enable(true)); |
| 141 | 148 | ||
| 142 | // Start sampling | 149 | // Start sampling |
| 143 | unsafe { r.tasks_start.write(|w| w.bits(1)) }; | 150 | r.tasks_start().write_value(1); |
| 144 | 151 | ||
| 145 | Self { _p: p } | 152 | Self { _p: p } |
| 146 | } | 153 | } |
| @@ -169,16 +176,16 @@ impl<'d, T: Instance> Qdec<'d, T> { | |||
| 169 | /// ``` | 176 | /// ``` |
| 170 | pub async fn read(&mut self) -> i16 { | 177 | pub async fn read(&mut self) -> i16 { |
| 171 | let t = T::regs(); | 178 | let t = T::regs(); |
| 172 | t.intenset.write(|w| w.reportrdy().set()); | 179 | t.intenset().write(|w| w.set_reportrdy(true)); |
| 173 | unsafe { t.tasks_readclracc.write(|w| w.bits(1)) }; | 180 | t.tasks_readclracc().write_value(1); |
| 174 | 181 | ||
| 175 | poll_fn(|cx| { | 182 | poll_fn(|cx| { |
| 176 | T::state().waker.register(cx.waker()); | 183 | T::state().waker.register(cx.waker()); |
| 177 | if t.events_reportrdy.read().bits() == 0 { | 184 | if t.events_reportrdy().read() == 0 { |
| 178 | Poll::Pending | 185 | Poll::Pending |
| 179 | } else { | 186 | } else { |
| 180 | t.events_reportrdy.reset(); | 187 | t.events_reportrdy().write_value(0); |
| 181 | let acc = t.accread.read().bits(); | 188 | let acc = t.accread().read(); |
| 182 | Poll::Ready(acc as i16) | 189 | Poll::Ready(acc as i16) |
| 183 | } | 190 | } |
| 184 | }) | 191 | }) |
| @@ -259,7 +266,7 @@ impl State { | |||
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | pub(crate) trait SealedInstance { | 268 | pub(crate) trait SealedInstance { |
| 262 | fn regs() -> &'static crate::pac::qdec::RegisterBlock; | 269 | fn regs() -> pac::qdec::Qdec; |
| 263 | fn state() -> &'static State; | 270 | fn state() -> &'static State; |
| 264 | } | 271 | } |
| 265 | 272 | ||
| @@ -273,8 +280,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 273 | macro_rules! impl_qdec { | 280 | macro_rules! impl_qdec { |
| 274 | ($type:ident, $pac_type:ident, $irq:ident) => { | 281 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 275 | impl crate::qdec::SealedInstance for peripherals::$type { | 282 | impl crate::qdec::SealedInstance for peripherals::$type { |
| 276 | fn regs() -> &'static crate::pac::qdec::RegisterBlock { | 283 | fn regs() -> pac::qdec::Qdec { |
| 277 | unsafe { &*pac::$pac_type::ptr() } | 284 | pac::$pac_type |
| 278 | } | 285 | } |
| 279 | fn state() -> &'static crate::qdec::State { | 286 | fn state() -> &'static crate::qdec::State { |
| 280 | static STATE: crate::qdec::State = crate::qdec::State::new(); | 287 | static STATE: crate::qdec::State = crate::qdec::State::new(); |
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index d40096edc..de9c268c1 100755 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs | |||
| @@ -14,11 +14,12 @@ use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashEr | |||
| 14 | 14 | ||
| 15 | use crate::gpio::{self, Pin as GpioPin}; | 15 | use crate::gpio::{self, Pin as GpioPin}; |
| 16 | use crate::interrupt::typelevel::Interrupt; | 16 | use crate::interrupt::typelevel::Interrupt; |
| 17 | pub use crate::pac::qspi::ifconfig0::{ | 17 | use crate::pac::gpio::vals as gpiovals; |
| 18 | ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode, | 18 | use crate::pac::qspi::vals; |
| 19 | pub use crate::pac::qspi::vals::{ | ||
| 20 | Addrmode as AddressMode, Ppsize as WritePageSize, Readoc as ReadOpcode, Spimode as SpiMode, Writeoc as WriteOpcode, | ||
| 19 | }; | 21 | }; |
| 20 | pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode; | 22 | use crate::{interrupt, pac, Peripheral}; |
| 21 | use crate::{interrupt, Peripheral}; | ||
| 22 | 23 | ||
| 23 | /// Deep power-down config. | 24 | /// Deep power-down config. |
| 24 | pub struct DeepPowerDownConfig { | 25 | pub struct DeepPowerDownConfig { |
| @@ -129,9 +130,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 129 | let r = T::regs(); | 130 | let r = T::regs(); |
| 130 | let s = T::state(); | 131 | let s = T::state(); |
| 131 | 132 | ||
| 132 | if r.events_ready.read().bits() != 0 { | 133 | if r.events_ready().read() != 0 { |
| 133 | s.waker.wake(); | 134 | s.waker.wake(); |
| 134 | r.intenclr.write(|w| w.ready().clear()); | 135 | r.intenclr().write(|w| w.set_ready(true)); |
| 135 | } | 136 | } |
| 136 | } | 137 | } |
| 137 | } | 138 | } |
| @@ -164,13 +165,12 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 164 | ($pin:ident) => { | 165 | ($pin:ident) => { |
| 165 | $pin.set_high(); | 166 | $pin.set_high(); |
| 166 | $pin.conf().write(|w| { | 167 | $pin.conf().write(|w| { |
| 167 | w.dir().output(); | 168 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 168 | w.drive().h0h1(); | 169 | w.set_drive(gpiovals::Drive::H0H1); |
| 169 | #[cfg(all(feature = "_nrf5340", feature = "_s"))] | 170 | #[cfg(all(feature = "_nrf5340", feature = "_s"))] |
| 170 | w.mcusel().peripheral(); | 171 | w.set_mcusel(gpiovals::Mcusel::PERIPHERAL); |
| 171 | w | ||
| 172 | }); | 172 | }); |
| 173 | r.psel.$pin.write(|w| unsafe { w.bits($pin.psel_bits()) }); | 173 | r.psel().$pin().write_value($pin.psel_bits()); |
| 174 | }; | 174 | }; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| @@ -181,46 +181,39 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 181 | config_pin!(io2); | 181 | config_pin!(io2); |
| 182 | config_pin!(io3); | 182 | config_pin!(io3); |
| 183 | 183 | ||
| 184 | r.ifconfig0.write(|w| { | 184 | r.ifconfig0().write(|w| { |
| 185 | w.addrmode().variant(config.address_mode); | 185 | w.set_addrmode(config.address_mode); |
| 186 | w.dpmenable().bit(config.deep_power_down.is_some()); | 186 | w.set_dpmenable(config.deep_power_down.is_some()); |
| 187 | w.ppsize().variant(config.write_page_size); | 187 | w.set_ppsize(config.write_page_size); |
| 188 | w.readoc().variant(config.read_opcode); | 188 | w.set_readoc(config.read_opcode); |
| 189 | w.writeoc().variant(config.write_opcode); | 189 | w.set_writeoc(config.write_opcode); |
| 190 | w | ||
| 191 | }); | 190 | }); |
| 192 | 191 | ||
| 193 | if let Some(dpd) = &config.deep_power_down { | 192 | if let Some(dpd) = &config.deep_power_down { |
| 194 | r.dpmdur.write(|w| unsafe { | 193 | r.dpmdur().write(|w| { |
| 195 | w.enter().bits(dpd.enter_time); | 194 | w.set_enter(dpd.enter_time); |
| 196 | w.exit().bits(dpd.exit_time); | 195 | w.set_exit(dpd.exit_time); |
| 197 | w | ||
| 198 | }) | 196 | }) |
| 199 | } | 197 | } |
| 200 | 198 | ||
| 201 | r.ifconfig1.write(|w| unsafe { | 199 | r.ifconfig1().write(|w| { |
| 202 | w.sckdelay().bits(config.sck_delay); | 200 | w.set_sckdelay(config.sck_delay); |
| 203 | w.dpmen().exit(); | 201 | w.set_dpmen(false); |
| 204 | w.spimode().variant(config.spi_mode); | 202 | w.set_spimode(config.spi_mode); |
| 205 | w.sckfreq().bits(config.frequency as u8); | 203 | w.set_sckfreq(config.frequency as u8); |
| 206 | w | ||
| 207 | }); | 204 | }); |
| 208 | 205 | ||
| 209 | r.iftiming.write(|w| unsafe { | 206 | r.iftiming().write(|w| { |
| 210 | w.rxdelay().bits(config.rx_delay & 0b111); | 207 | w.set_rxdelay(config.rx_delay & 0b111); |
| 211 | w | ||
| 212 | }); | 208 | }); |
| 213 | 209 | ||
| 214 | r.xipoffset.write(|w| unsafe { | 210 | r.xipoffset().write_value(config.xip_offset); |
| 215 | w.xipoffset().bits(config.xip_offset); | ||
| 216 | w | ||
| 217 | }); | ||
| 218 | 211 | ||
| 219 | T::Interrupt::unpend(); | 212 | T::Interrupt::unpend(); |
| 220 | unsafe { T::Interrupt::enable() }; | 213 | unsafe { T::Interrupt::enable() }; |
| 221 | 214 | ||
| 222 | // Enable it | 215 | // Enable it |
| 223 | r.enable.write(|w| w.enable().enabled()); | 216 | r.enable().write(|w| w.set_enable(true)); |
| 224 | 217 | ||
| 225 | let res = Self { | 218 | let res = Self { |
| 226 | _peri: qspi, | 219 | _peri: qspi, |
| @@ -228,10 +221,10 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 228 | capacity: config.capacity, | 221 | capacity: config.capacity, |
| 229 | }; | 222 | }; |
| 230 | 223 | ||
| 231 | r.events_ready.reset(); | 224 | r.events_ready().write_value(0); |
| 232 | r.intenset.write(|w| w.ready().set()); | 225 | r.intenset().write(|w| w.set_ready(true)); |
| 233 | 226 | ||
| 234 | r.tasks_activate.write(|w| w.tasks_activate().bit(true)); | 227 | r.tasks_activate().write_value(1); |
| 235 | 228 | ||
| 236 | Self::blocking_wait_ready(); | 229 | Self::blocking_wait_ready(); |
| 237 | 230 | ||
| @@ -284,22 +277,21 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 284 | } | 277 | } |
| 285 | 278 | ||
| 286 | let r = T::regs(); | 279 | let r = T::regs(); |
| 287 | r.cinstrdat0.write(|w| unsafe { w.bits(dat0) }); | 280 | r.cinstrdat0().write(|w| w.0 = dat0); |
| 288 | r.cinstrdat1.write(|w| unsafe { w.bits(dat1) }); | 281 | r.cinstrdat1().write(|w| w.0 = dat1); |
| 289 | 282 | ||
| 290 | r.events_ready.reset(); | 283 | r.events_ready().write_value(0); |
| 291 | r.intenset.write(|w| w.ready().set()); | 284 | r.intenset().write(|w| w.set_ready(true)); |
| 292 | 285 | ||
| 293 | r.cinstrconf.write(|w| { | 286 | r.cinstrconf().write(|w| { |
| 294 | let w = unsafe { w.opcode().bits(opcode) }; | 287 | w.set_opcode(opcode); |
| 295 | let w = unsafe { w.length().bits(len + 1) }; | 288 | w.set_length(vals::Length::from_bits(len + 1)); |
| 296 | let w = w.lio2().bit(true); | 289 | w.set_lio2(true); |
| 297 | let w = w.lio3().bit(true); | 290 | w.set_lio3(true); |
| 298 | let w = w.wipwait().bit(true); | 291 | w.set_wipwait(true); |
| 299 | let w = w.wren().bit(true); | 292 | w.set_wren(true); |
| 300 | let w = w.lfen().bit(false); | 293 | w.set_lfen(false); |
| 301 | let w = w.lfstop().bit(false); | 294 | w.set_lfstop(false); |
| 302 | w | ||
| 303 | }); | 295 | }); |
| 304 | Ok(()) | 296 | Ok(()) |
| 305 | } | 297 | } |
| @@ -307,8 +299,8 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 307 | fn custom_instruction_finish(&mut self, resp: &mut [u8]) -> Result<(), Error> { | 299 | fn custom_instruction_finish(&mut self, resp: &mut [u8]) -> Result<(), Error> { |
| 308 | let r = T::regs(); | 300 | let r = T::regs(); |
| 309 | 301 | ||
| 310 | let dat0 = r.cinstrdat0.read().bits(); | 302 | let dat0 = r.cinstrdat0().read().0; |
| 311 | let dat1 = r.cinstrdat1.read().bits(); | 303 | let dat1 = r.cinstrdat1().read().0; |
| 312 | for i in 0..4 { | 304 | for i in 0..4 { |
| 313 | if i < resp.len() { | 305 | if i < resp.len() { |
| 314 | resp[i] = (dat0 >> (i * 8)) as u8; | 306 | resp[i] = (dat0 >> (i * 8)) as u8; |
| @@ -327,7 +319,7 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 327 | let r = T::regs(); | 319 | let r = T::regs(); |
| 328 | let s = T::state(); | 320 | let s = T::state(); |
| 329 | s.waker.register(cx.waker()); | 321 | s.waker.register(cx.waker()); |
| 330 | if r.events_ready.read().bits() != 0 { | 322 | if r.events_ready().read() != 0 { |
| 331 | return Poll::Ready(()); | 323 | return Poll::Ready(()); |
| 332 | } | 324 | } |
| 333 | Poll::Pending | 325 | Poll::Pending |
| @@ -338,7 +330,7 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 338 | fn blocking_wait_ready() { | 330 | fn blocking_wait_ready() { |
| 339 | loop { | 331 | loop { |
| 340 | let r = T::regs(); | 332 | let r = T::regs(); |
| 341 | if r.events_ready.read().bits() != 0 { | 333 | if r.events_ready().read() != 0 { |
| 342 | break; | 334 | break; |
| 343 | } | 335 | } |
| 344 | } | 336 | } |
| @@ -352,13 +344,13 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 352 | 344 | ||
| 353 | let r = T::regs(); | 345 | let r = T::regs(); |
| 354 | 346 | ||
| 355 | r.read.src.write(|w| unsafe { w.src().bits(address) }); | 347 | r.read().src().write_value(address); |
| 356 | r.read.dst.write(|w| unsafe { w.dst().bits(data.as_ptr() as u32) }); | 348 | r.read().dst().write_value(data.as_ptr() as u32); |
| 357 | r.read.cnt.write(|w| unsafe { w.cnt().bits(data.len() as u32) }); | 349 | r.read().cnt().write(|w| w.set_cnt(data.len() as u32)); |
| 358 | 350 | ||
| 359 | r.events_ready.reset(); | 351 | r.events_ready().write_value(0); |
| 360 | r.intenset.write(|w| w.ready().set()); | 352 | r.intenset().write(|w| w.set_ready(true)); |
| 361 | r.tasks_readstart.write(|w| w.tasks_readstart().bit(true)); | 353 | r.tasks_readstart().write_value(1); |
| 362 | 354 | ||
| 363 | Ok(()) | 355 | Ok(()) |
| 364 | } | 356 | } |
| @@ -370,13 +362,13 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 370 | assert_eq!(address % 4, 0); | 362 | assert_eq!(address % 4, 0); |
| 371 | 363 | ||
| 372 | let r = T::regs(); | 364 | let r = T::regs(); |
| 373 | r.write.src.write(|w| unsafe { w.src().bits(data.as_ptr() as u32) }); | 365 | r.write().src().write_value(data.as_ptr() as u32); |
| 374 | r.write.dst.write(|w| unsafe { w.dst().bits(address) }); | 366 | r.write().dst().write_value(address); |
| 375 | r.write.cnt.write(|w| unsafe { w.cnt().bits(data.len() as u32) }); | 367 | r.write().cnt().write(|w| w.set_cnt(data.len() as u32)); |
| 376 | 368 | ||
| 377 | r.events_ready.reset(); | 369 | r.events_ready().write_value(0); |
| 378 | r.intenset.write(|w| w.ready().set()); | 370 | r.intenset().write(|w| w.set_ready(true)); |
| 379 | r.tasks_writestart.write(|w| w.tasks_writestart().bit(true)); | 371 | r.tasks_writestart().write_value(1); |
| 380 | 372 | ||
| 381 | Ok(()) | 373 | Ok(()) |
| 382 | } | 374 | } |
| @@ -386,12 +378,12 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 386 | assert_eq!(address % 4096, 0); | 378 | assert_eq!(address % 4096, 0); |
| 387 | 379 | ||
| 388 | let r = T::regs(); | 380 | let r = T::regs(); |
| 389 | r.erase.ptr.write(|w| unsafe { w.ptr().bits(address) }); | 381 | r.erase().ptr().write_value(address); |
| 390 | r.erase.len.write(|w| w.len()._4kb()); | 382 | r.erase().len().write(|w| w.set_len(vals::Len::_4KB)); |
| 391 | 383 | ||
| 392 | r.events_ready.reset(); | 384 | r.events_ready().write_value(0); |
| 393 | r.intenset.write(|w| w.ready().set()); | 385 | r.intenset().write(|w| w.set_ready(true)); |
| 394 | r.tasks_erasestart.write(|w| w.tasks_erasestart().bit(true)); | 386 | r.tasks_erasestart().write_value(1); |
| 395 | 387 | ||
| 396 | Ok(()) | 388 | Ok(()) |
| 397 | } | 389 | } |
| @@ -538,12 +530,12 @@ impl<'d, T: Instance> Drop for Qspi<'d, T> { | |||
| 538 | if self.dpm_enabled { | 530 | if self.dpm_enabled { |
| 539 | trace!("qspi: doing deep powerdown..."); | 531 | trace!("qspi: doing deep powerdown..."); |
| 540 | 532 | ||
| 541 | r.ifconfig1.modify(|_, w| w.dpmen().enter()); | 533 | r.ifconfig1().modify(|w| w.set_dpmen(true)); |
| 542 | 534 | ||
| 543 | // Wait for DPM enter. | 535 | // Wait for DPM enter. |
| 544 | // Unfortunately we must spin. There's no way to do this interrupt-driven. | 536 | // Unfortunately we must spin. There's no way to do this interrupt-driven. |
| 545 | // The READY event does NOT fire on DPM enter (but it does fire on DPM exit :shrug:) | 537 | // The READY event does NOT fire on DPM enter (but it does fire on DPM exit :shrug:) |
| 546 | while r.status.read().dpm().is_disabled() {} | 538 | while !r.status().read().dpm() {} |
| 547 | 539 | ||
| 548 | // Wait MORE for DPM enter. | 540 | // Wait MORE for DPM enter. |
| 549 | // I have absolutely no idea why, but the wait above is not enough :'( | 541 | // I have absolutely no idea why, but the wait above is not enough :'( |
| @@ -552,23 +544,23 @@ impl<'d, T: Instance> Drop for Qspi<'d, T> { | |||
| 552 | } | 544 | } |
| 553 | 545 | ||
| 554 | // it seems events_ready is not generated in response to deactivate. nrfx doesn't wait for it. | 546 | // it seems events_ready is not generated in response to deactivate. nrfx doesn't wait for it. |
| 555 | r.tasks_deactivate.write(|w| w.tasks_deactivate().set_bit()); | 547 | r.tasks_deactivate().write_value(1); |
| 556 | 548 | ||
| 557 | // Workaround https://infocenter.nordicsemi.com/topic/errata_nRF52840_Rev1/ERR/nRF52840/Rev1/latest/anomaly_840_122.html?cp=4_0_1_2_1_7 | 549 | // Workaround https://infocenter.nordicsemi.com/topic/errata_nRF52840_Rev1/ERR/nRF52840/Rev1/latest/anomaly_840_122.html?cp=4_0_1_2_1_7 |
| 558 | // Note that the doc has 2 register writes, but the first one is really the write to tasks_deactivate, | 550 | // Note that the doc has 2 register writes, but the first one is really the write to tasks_deactivate, |
| 559 | // so we only do the second one here. | 551 | // so we only do the second one here. |
| 560 | unsafe { ptr::write_volatile(0x40029054 as *mut u32, 1) } | 552 | unsafe { ptr::write_volatile(0x40029054 as *mut u32, 1) } |
| 561 | 553 | ||
| 562 | r.enable.write(|w| w.enable().disabled()); | 554 | r.enable().write(|w| w.set_enable(false)); |
| 563 | 555 | ||
| 564 | // Note: we do NOT deconfigure CSN here. If DPM is in use and we disconnect CSN, | 556 | // Note: we do NOT deconfigure CSN here. If DPM is in use and we disconnect CSN, |
| 565 | // leaving it floating, the flash chip might read it as zero which would cause it to | 557 | // leaving it floating, the flash chip might read it as zero which would cause it to |
| 566 | // spuriously exit DPM. | 558 | // spuriously exit DPM. |
| 567 | gpio::deconfigure_pin(r.psel.sck.read().bits()); | 559 | gpio::deconfigure_pin(r.psel().sck().read()); |
| 568 | gpio::deconfigure_pin(r.psel.io0.read().bits()); | 560 | gpio::deconfigure_pin(r.psel().io0().read()); |
| 569 | gpio::deconfigure_pin(r.psel.io1.read().bits()); | 561 | gpio::deconfigure_pin(r.psel().io1().read()); |
| 570 | gpio::deconfigure_pin(r.psel.io2.read().bits()); | 562 | gpio::deconfigure_pin(r.psel().io2().read()); |
| 571 | gpio::deconfigure_pin(r.psel.io3.read().bits()); | 563 | gpio::deconfigure_pin(r.psel().io3().read()); |
| 572 | 564 | ||
| 573 | trace!("qspi: dropped"); | 565 | trace!("qspi: dropped"); |
| 574 | } | 566 | } |
| @@ -667,7 +659,7 @@ impl State { | |||
| 667 | } | 659 | } |
| 668 | 660 | ||
| 669 | pub(crate) trait SealedInstance { | 661 | pub(crate) trait SealedInstance { |
| 670 | fn regs() -> &'static crate::pac::qspi::RegisterBlock; | 662 | fn regs() -> pac::qspi::Qspi; |
| 671 | fn state() -> &'static State; | 663 | fn state() -> &'static State; |
| 672 | } | 664 | } |
| 673 | 665 | ||
| @@ -681,8 +673,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 681 | macro_rules! impl_qspi { | 673 | macro_rules! impl_qspi { |
| 682 | ($type:ident, $pac_type:ident, $irq:ident) => { | 674 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 683 | impl crate::qspi::SealedInstance for peripherals::$type { | 675 | impl crate::qspi::SealedInstance for peripherals::$type { |
| 684 | fn regs() -> &'static crate::pac::qspi::RegisterBlock { | 676 | fn regs() -> pac::qspi::Qspi { |
| 685 | unsafe { &*pac::$pac_type::ptr() } | 677 | pac::$pac_type |
| 686 | } | 678 | } |
| 687 | fn state() -> &'static crate::qspi::State { | 679 | fn state() -> &'static crate::qspi::State { |
| 688 | static STATE: crate::qspi::State = crate::qspi::State::new(); | 680 | static STATE: crate::qspi::State = crate::qspi::State::new(); |
diff --git a/embassy-nrf/src/radio/ble.rs b/embassy-nrf/src/radio/ble.rs index 4f0b0641f..682ca1c79 100644 --- a/embassy-nrf/src/radio/ble.rs +++ b/embassy-nrf/src/radio/ble.rs | |||
| @@ -6,11 +6,12 @@ use core::task::Poll; | |||
| 6 | 6 | ||
| 7 | use embassy_hal_internal::drop::OnDrop; | 7 | use embassy_hal_internal::drop::OnDrop; |
| 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 8 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 9 | pub use pac::radio::mode::MODE_A as Mode; | 9 | pub use pac::radio::vals::Mode; |
| 10 | #[cfg(not(feature = "nrf51"))] | 10 | #[cfg(not(feature = "_nrf51"))] |
| 11 | use pac::radio::pcnf0::PLEN_A as PreambleLength; | 11 | use pac::radio::vals::Plen as PreambleLength; |
| 12 | 12 | ||
| 13 | use crate::interrupt::typelevel::Interrupt; | 13 | use crate::interrupt::typelevel::Interrupt; |
| 14 | use crate::pac::radio::vals; | ||
| 14 | use crate::radio::*; | 15 | use crate::radio::*; |
| 15 | pub use crate::radio::{Error, TxPower}; | 16 | pub use crate::radio::{Error, TxPower}; |
| 16 | use crate::util::slice_in_ram_or; | 17 | use crate::util::slice_in_ram_or; |
| @@ -30,69 +31,63 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 30 | 31 | ||
| 31 | let r = T::regs(); | 32 | let r = T::regs(); |
| 32 | 33 | ||
| 33 | r.pcnf1.write(|w| unsafe { | 34 | r.pcnf1().write(|w| { |
| 34 | // It is 0 bytes long in a standard BLE packet | 35 | // It is 0 bytes long in a standard BLE packet |
| 35 | w.statlen() | 36 | w.set_statlen(0); |
| 36 | .bits(0) | 37 | // MaxLen configures the maximum packet payload plus add-on size in |
| 37 | // MaxLen configures the maximum packet payload plus add-on size in | 38 | // number of bytes that can be transmitted or received by the RADIO. This feature can be used to ensure |
| 38 | // number of bytes that can be transmitted or received by the RADIO. This feature can be used to ensure | 39 | // that the RADIO does not overwrite, or read beyond, the RAM assigned to the packet payload. This means |
| 39 | // that the RADIO does not overwrite, or read beyond, the RAM assigned to the packet payload. This means | 40 | // that if the packet payload length defined by PCNF1.STATLEN and the LENGTH field in the packet specifies a |
| 40 | // that if the packet payload length defined by PCNF1.STATLEN and the LENGTH field in the packet specifies a | 41 | // packet larger than MAXLEN, the payload will be truncated at MAXLEN |
| 41 | // packet larger than MAXLEN, the payload will be truncated at MAXLEN | 42 | // |
| 42 | // | 43 | // To simplify the implementation, It is setted as the maximum value |
| 43 | // To simplify the implementation, It is setted as the maximum value | 44 | // and the length of the packet is controlled only by the LENGTH field in the packet |
| 44 | // and the length of the packet is controlled only by the LENGTH field in the packet | 45 | w.set_maxlen(255); |
| 45 | .maxlen() | 46 | // Configure the length of the address field in the packet |
| 46 | .bits(255) | 47 | // The prefix after the address fields is always appended, so is always 1 byte less than the size of the address |
| 47 | // Configure the length of the address field in the packet | 48 | // The base address is truncated from the least significant byte if the BALEN is less than 4 |
| 48 | // The prefix after the address fields is always appended, so is always 1 byte less than the size of the address | 49 | // |
| 49 | // The base address is truncated from the least significant byte if the BALEN is less than 4 | 50 | // BLE address is always 4 bytes long |
| 50 | // | 51 | w.set_balen(3); // 3 bytes base address (+ 1 prefix); |
| 51 | // BLE address is always 4 bytes long | 52 | // Configure the endianess |
| 52 | .balen() | 53 | // For BLE is always little endian (LSB first) |
| 53 | .bits(3) // 3 bytes base address (+ 1 prefix); | 54 | w.set_endian(vals::Endian::LITTLE); |
| 54 | // Configure the endianess | 55 | // Data whitening is used to avoid long sequences of zeros or |
| 55 | // For BLE is always little endian (LSB first) | 56 | // ones, e.g., 0b0000000 or 0b1111111, in the data bit stream. |
| 56 | .endian() | 57 | // The whitener and de-whitener are defined the same way, |
| 57 | .little() | 58 | // using a 7-bit linear feedback shift register with the |
| 58 | // Data whitening is used to avoid long sequences of zeros or | 59 | // polynomial x7 + x4 + 1. |
| 59 | // ones, e.g., 0b0000000 or 0b1111111, in the data bit stream. | 60 | // |
| 60 | // The whitener and de-whitener are defined the same way, | 61 | // In BLE Whitening shall be applied on the PDU and CRC of all |
| 61 | // using a 7-bit linear feedback shift register with the | 62 | // Link Layer packets and is performed after the CRC generation |
| 62 | // polynomial x7 + x4 + 1. | 63 | // in the transmitter. No other parts of the packets are whitened. |
| 63 | // | 64 | // De-whitening is performed before the CRC checking in the receiver |
| 64 | // In BLE Whitening shall be applied on the PDU and CRC of all | 65 | // Before whitening or de-whitening, the shift register should be |
| 65 | // Link Layer packets and is performed after the CRC generation | 66 | // initialized based on the channel index. |
| 66 | // in the transmitter. No other parts of the packets are whitened. | 67 | w.set_whiteen(true); |
| 67 | // De-whitening is performed before the CRC checking in the receiver | ||
| 68 | // Before whitening or de-whitening, the shift register should be | ||
| 69 | // initialized based on the channel index. | ||
| 70 | .whiteen() | ||
| 71 | .set_bit() | ||
| 72 | }); | 68 | }); |
| 73 | 69 | ||
| 74 | // Configure CRC | 70 | // Configure CRC |
| 75 | r.crccnf.write(|w| { | 71 | r.crccnf().write(|w| { |
| 76 | // In BLE the CRC shall be calculated on the PDU of all Link Layer | 72 | // In BLE the CRC shall be calculated on the PDU of all Link Layer |
| 77 | // packets (even if the packet is encrypted). | 73 | // packets (even if the packet is encrypted). |
| 78 | // It skips the address field | 74 | // It skips the address field |
| 79 | w.skipaddr() | 75 | w.set_skipaddr(vals::Skipaddr::SKIP); |
| 80 | .skip() | 76 | // In BLE 24-bit CRC = 3 bytes |
| 81 | // In BLE 24-bit CRC = 3 bytes | 77 | w.set_len(vals::Len::THREE); |
| 82 | .len() | ||
| 83 | .three() | ||
| 84 | }); | 78 | }); |
| 85 | 79 | ||
| 86 | // Ch map between 2400 MHZ .. 2500 MHz | 80 | // Ch map between 2400 MHZ .. 2500 MHz |
| 87 | // All modes use this range | 81 | // All modes use this range |
| 88 | #[cfg(not(feature = "nrf51"))] | 82 | #[cfg(not(feature = "_nrf51"))] |
| 89 | r.frequency.write(|w| w.map().default()); | 83 | r.frequency().write(|w| w.set_map(vals::Map::DEFAULT)); |
| 90 | 84 | ||
| 91 | // Configure shortcuts to simplify and speed up sending and receiving packets. | 85 | // Configure shortcuts to simplify and speed up sending and receiving packets. |
| 92 | r.shorts.write(|w| { | 86 | r.shorts().write(|w| { |
| 93 | // start transmission/recv immediately after ramp-up | 87 | // start transmission/recv immediately after ramp-up |
| 94 | // disable radio when transmission/recv is done | 88 | // disable radio when transmission/recv is done |
| 95 | w.ready_start().enabled().end_disable().enabled() | 89 | w.set_ready_start(true); |
| 90 | w.set_end_disable(true); | ||
| 96 | }); | 91 | }); |
| 97 | 92 | ||
| 98 | // Enable NVIC interrupt | 93 | // Enable NVIC interrupt |
| @@ -113,11 +108,11 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 113 | assert!(self.state() == RadioState::DISABLED); | 108 | assert!(self.state() == RadioState::DISABLED); |
| 114 | 109 | ||
| 115 | let r = T::regs(); | 110 | let r = T::regs(); |
| 116 | r.mode.write(|w| w.mode().variant(mode)); | 111 | r.mode().write(|w| w.set_mode(mode)); |
| 117 | 112 | ||
| 118 | #[cfg(not(feature = "nrf51"))] | 113 | #[cfg(not(feature = "_nrf51"))] |
| 119 | r.pcnf0.write(|w| { | 114 | r.pcnf0().write(|w| { |
| 120 | w.plen().variant(match mode { | 115 | w.set_plen(match mode { |
| 121 | Mode::BLE_1MBIT => PreambleLength::_8BIT, | 116 | Mode::BLE_1MBIT => PreambleLength::_8BIT, |
| 122 | Mode::BLE_2MBIT => PreambleLength::_16BIT, | 117 | Mode::BLE_2MBIT => PreambleLength::_16BIT, |
| 123 | #[cfg(any( | 118 | #[cfg(any( |
| @@ -147,18 +142,14 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 147 | true => 8, | 142 | true => 8, |
| 148 | }; | 143 | }; |
| 149 | 144 | ||
| 150 | r.pcnf0.write(|w| unsafe { | 145 | r.pcnf0().write(|w| { |
| 151 | w | 146 | // Configure S0 to 1 byte length, this will represent the Data/Adv header flags |
| 152 | // Configure S0 to 1 byte length, this will represent the Data/Adv header flags | 147 | w.set_s0len(true); |
| 153 | .s0len() | 148 | // Configure the length (in bits) field to 1 byte length, this will represent the length of the payload |
| 154 | .set_bit() | 149 | // and also be used to know how many bytes to read/write from/to the buffer |
| 155 | // Configure the length (in bits) field to 1 byte length, this will represent the length of the payload | 150 | w.set_lflen(0); |
| 156 | // and also be used to know how many bytes to read/write from/to the buffer | 151 | // Configure the lengh (in bits) of bits in the S1 field. It could be used to represent the CTEInfo for data packages in BLE. |
| 157 | .lflen() | 152 | w.set_s1len(s1len); |
| 158 | .bits(8) | ||
| 159 | // Configure the lengh (in bits) of bits in the S1 field. It could be used to represent the CTEInfo for data packages in BLE. | ||
| 160 | .s1len() | ||
| 161 | .bits(s1len) | ||
| 162 | }); | 153 | }); |
| 163 | } | 154 | } |
| 164 | 155 | ||
| @@ -172,7 +163,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 172 | 163 | ||
| 173 | let r = T::regs(); | 164 | let r = T::regs(); |
| 174 | 165 | ||
| 175 | r.datawhiteiv.write(|w| unsafe { w.datawhiteiv().bits(whitening_init) }); | 166 | r.datawhiteiv().write(|w| w.set_datawhiteiv(whitening_init)); |
| 176 | } | 167 | } |
| 177 | 168 | ||
| 178 | /// Set the central frequency to be used | 169 | /// Set the central frequency to be used |
| @@ -185,8 +176,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 185 | 176 | ||
| 186 | let r = T::regs(); | 177 | let r = T::regs(); |
| 187 | 178 | ||
| 188 | r.frequency | 179 | r.frequency().write(|w| w.set_frequency((frequency - 2400) as u8)); |
| 189 | .write(|w| unsafe { w.frequency().bits((frequency - 2400) as u8) }); | ||
| 190 | } | 180 | } |
| 191 | 181 | ||
| 192 | /// Set the acess address | 182 | /// Set the acess address |
| @@ -204,31 +194,25 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 204 | // The byte ordering on air is always least significant byte first for the address | 194 | // The byte ordering on air is always least significant byte first for the address |
| 205 | // So for the address 0xAA_BB_CC_DD, the address on air will be DD CC BB AA | 195 | // So for the address 0xAA_BB_CC_DD, the address on air will be DD CC BB AA |
| 206 | // The package order is BASE, PREFIX so BASE=0xBB_CC_DD and PREFIX=0xAA | 196 | // The package order is BASE, PREFIX so BASE=0xBB_CC_DD and PREFIX=0xAA |
| 207 | r.prefix0 | 197 | r.prefix0().write(|w| w.set_ap0((access_address >> 24) as u8)); |
| 208 | .write(|w| unsafe { w.ap0().bits((access_address >> 24) as u8) }); | ||
| 209 | 198 | ||
| 210 | // The base address is truncated from the least significant byte (because the BALEN is less than 4) | 199 | // The base address is truncated from the least significant byte (because the BALEN is less than 4) |
| 211 | // So it shifts the address to the right | 200 | // So it shifts the address to the right |
| 212 | r.base0.write(|w| unsafe { w.bits(access_address << 8) }); | 201 | r.base0().write_value(access_address << 8); |
| 213 | 202 | ||
| 214 | // Don't match tx address | 203 | // Don't match tx address |
| 215 | r.txaddress.write(|w| unsafe { w.txaddress().bits(0) }); | 204 | r.txaddress().write(|w| w.set_txaddress(0)); |
| 216 | 205 | ||
| 217 | // Match on logical address | 206 | // Match on logical address |
| 218 | // This config only filter the packets by the address, | 207 | // This config only filter the packets by the address, |
| 219 | // so only packages send to the previous address | 208 | // so only packages send to the previous address |
| 220 | // will finish the reception (TODO: check the explanation) | 209 | // will finish the reception (TODO: check the explanation) |
| 221 | r.rxaddresses.write(|w| { | 210 | r.rxaddresses().write(|w| { |
| 222 | w.addr0() | 211 | w.set_addr0(true); |
| 223 | .enabled() | 212 | w.set_addr1(true); |
| 224 | .addr1() | 213 | w.set_addr2(true); |
| 225 | .enabled() | 214 | w.set_addr3(true); |
| 226 | .addr2() | 215 | w.set_addr4(true); |
| 227 | .enabled() | ||
| 228 | .addr3() | ||
| 229 | .enabled() | ||
| 230 | .addr4() | ||
| 231 | .enabled() | ||
| 232 | }); | 216 | }); |
| 233 | } | 217 | } |
| 234 | 218 | ||
| @@ -241,7 +225,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 241 | 225 | ||
| 242 | let r = T::regs(); | 226 | let r = T::regs(); |
| 243 | 227 | ||
| 244 | r.crcpoly.write(|w| unsafe { | 228 | r.crcpoly().write(|w| { |
| 245 | // Configure the CRC polynomial | 229 | // Configure the CRC polynomial |
| 246 | // Each term in the CRC polynomial is mapped to a bit in this | 230 | // Each term in the CRC polynomial is mapped to a bit in this |
| 247 | // register which index corresponds to the term's exponent. | 231 | // register which index corresponds to the term's exponent. |
| @@ -249,7 +233,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 249 | // 1, and bit number 0 of the register content is ignored by | 233 | // 1, and bit number 0 of the register content is ignored by |
| 250 | // the hardware. The following example is for an 8 bit CRC | 234 | // the hardware. The following example is for an 8 bit CRC |
| 251 | // polynomial: x8 + x7 + x3 + x2 + 1 = 1 1000 1101 . | 235 | // polynomial: x8 + x7 + x3 + x2 + 1 = 1 1000 1101 . |
| 252 | w.crcpoly().bits(crc_poly & 0xFFFFFF) | 236 | w.set_crcpoly(crc_poly & 0xFFFFFF) |
| 253 | }); | 237 | }); |
| 254 | } | 238 | } |
| 255 | 239 | ||
| @@ -263,7 +247,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 263 | 247 | ||
| 264 | let r = T::regs(); | 248 | let r = T::regs(); |
| 265 | 249 | ||
| 266 | r.crcinit.write(|w| unsafe { w.crcinit().bits(crc_init & 0xFFFFFF) }); | 250 | r.crcinit().write(|w| w.set_crcinit(crc_init & 0xFFFFFF)); |
| 267 | } | 251 | } |
| 268 | 252 | ||
| 269 | /// Set the radio tx power | 253 | /// Set the radio tx power |
| @@ -274,7 +258,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 274 | 258 | ||
| 275 | let r = T::regs(); | 259 | let r = T::regs(); |
| 276 | 260 | ||
| 277 | r.txpower.write(|w| w.txpower().variant(tx_power)); | 261 | r.txpower().write(|w| w.set_txpower(tx_power)); |
| 278 | } | 262 | } |
| 279 | 263 | ||
| 280 | /// Set buffer to read/write | 264 | /// Set buffer to read/write |
| @@ -294,7 +278,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 294 | let ptr = buffer.as_ptr(); | 278 | let ptr = buffer.as_ptr(); |
| 295 | 279 | ||
| 296 | // Configure the payload | 280 | // Configure the payload |
| 297 | r.packetptr.write(|w| unsafe { w.bits(ptr as u32) }); | 281 | r.packetptr().write_value(ptr as u32); |
| 298 | 282 | ||
| 299 | Ok(()) | 283 | Ok(()) |
| 300 | } | 284 | } |
| @@ -310,7 +294,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 310 | // Initialize the transmission | 294 | // Initialize the transmission |
| 311 | // trace!("txen"); | 295 | // trace!("txen"); |
| 312 | 296 | ||
| 313 | r.tasks_txen.write(|w| unsafe { w.bits(1) }); | 297 | r.tasks_txen().write_value(1); |
| 314 | }) | 298 | }) |
| 315 | .await; | 299 | .await; |
| 316 | 300 | ||
| @@ -327,7 +311,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 327 | self.trigger_and_wait_end(move || { | 311 | self.trigger_and_wait_end(move || { |
| 328 | // Initialize the transmission | 312 | // Initialize the transmission |
| 329 | // trace!("rxen"); | 313 | // trace!("rxen"); |
| 330 | r.tasks_rxen.write(|w| unsafe { w.bits(1) }); | 314 | r.tasks_rxen().write_value(1); |
| 331 | }) | 315 | }) |
| 332 | .await; | 316 | .await; |
| 333 | 317 | ||
| @@ -344,21 +328,21 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 344 | let drop = OnDrop::new(|| { | 328 | let drop = OnDrop::new(|| { |
| 345 | trace!("radio drop: stopping"); | 329 | trace!("radio drop: stopping"); |
| 346 | 330 | ||
| 347 | r.intenclr.write(|w| w.end().clear()); | 331 | r.intenclr().write(|w| w.set_end(true)); |
| 348 | 332 | ||
| 349 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 333 | r.tasks_stop().write_value(1); |
| 350 | 334 | ||
| 351 | r.events_end.reset(); | 335 | r.events_end().write_value(0); |
| 352 | 336 | ||
| 353 | trace!("radio drop: stopped"); | 337 | trace!("radio drop: stopped"); |
| 354 | }); | 338 | }); |
| 355 | 339 | ||
| 356 | // trace!("radio:enable interrupt"); | 340 | // trace!("radio:enable interrupt"); |
| 357 | // Clear some remnant side-effects (TODO: check if this is necessary) | 341 | // Clear some remnant side-effects (TODO: check if this is necessary) |
| 358 | r.events_end.reset(); | 342 | r.events_end().write_value(0); |
| 359 | 343 | ||
| 360 | // Enable interrupt | 344 | // Enable interrupt |
| 361 | r.intenset.write(|w| w.end().set()); | 345 | r.intenset().write(|w| w.set_end(true)); |
| 362 | 346 | ||
| 363 | compiler_fence(Ordering::SeqCst); | 347 | compiler_fence(Ordering::SeqCst); |
| 364 | 348 | ||
| @@ -368,7 +352,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 368 | // On poll check if interrupt happen | 352 | // On poll check if interrupt happen |
| 369 | poll_fn(|cx| { | 353 | poll_fn(|cx| { |
| 370 | s.event_waker.register(cx.waker()); | 354 | s.event_waker.register(cx.waker()); |
| 371 | if r.events_end.read().bits() == 1 { | 355 | if r.events_end().read() == 1 { |
| 372 | // trace!("radio:end"); | 356 | // trace!("radio:end"); |
| 373 | return core::task::Poll::Ready(()); | 357 | return core::task::Poll::Ready(()); |
| 374 | } | 358 | } |
| @@ -377,7 +361,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 377 | .await; | 361 | .await; |
| 378 | 362 | ||
| 379 | compiler_fence(Ordering::SeqCst); | 363 | compiler_fence(Ordering::SeqCst); |
| 380 | r.events_end.reset(); // ACK | 364 | r.events_end().write_value(0); // ACK |
| 381 | 365 | ||
| 382 | // Everthing ends fine, so it disable the drop | 366 | // Everthing ends fine, so it disable the drop |
| 383 | drop.defuse(); | 367 | drop.defuse(); |
| @@ -392,15 +376,15 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 392 | if self.state() != RadioState::DISABLED { | 376 | if self.state() != RadioState::DISABLED { |
| 393 | trace!("radio:disable"); | 377 | trace!("radio:disable"); |
| 394 | // Trigger the disable task | 378 | // Trigger the disable task |
| 395 | r.tasks_disable.write(|w| unsafe { w.bits(1) }); | 379 | r.tasks_disable().write_value(1); |
| 396 | 380 | ||
| 397 | // Wait until the radio is disabled | 381 | // Wait until the radio is disabled |
| 398 | while r.events_disabled.read().bits() == 0 {} | 382 | while r.events_disabled().read() == 0 {} |
| 399 | 383 | ||
| 400 | compiler_fence(Ordering::SeqCst); | 384 | compiler_fence(Ordering::SeqCst); |
| 401 | 385 | ||
| 402 | // Acknowledge it | 386 | // Acknowledge it |
| 403 | r.events_disabled.reset(); | 387 | r.events_disabled().write_value(0); |
| 404 | } | 388 | } |
| 405 | } | 389 | } |
| 406 | } | 390 | } |
diff --git a/embassy-nrf/src/radio/ieee802154.rs b/embassy-nrf/src/radio/ieee802154.rs index 298f8a574..083842f4a 100644 --- a/embassy-nrf/src/radio/ieee802154.rs +++ b/embassy-nrf/src/radio/ieee802154.rs | |||
| @@ -9,6 +9,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 9 | use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower}; | 9 | use super::{state, Error, Instance, InterruptHandler, RadioState, TxPower}; |
| 10 | use crate::interrupt::typelevel::Interrupt; | 10 | use crate::interrupt::typelevel::Interrupt; |
| 11 | use crate::interrupt::{self}; | 11 | use crate::interrupt::{self}; |
| 12 | use crate::pac::radio::vals; | ||
| 12 | use crate::Peripheral; | 13 | use crate::Peripheral; |
| 13 | 14 | ||
| 14 | /// Default (IEEE compliant) Start of Frame Delimiter | 15 | /// Default (IEEE compliant) Start of Frame Delimiter |
| @@ -47,58 +48,47 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 47 | let r = T::regs(); | 48 | let r = T::regs(); |
| 48 | 49 | ||
| 49 | // Disable and enable to reset peripheral | 50 | // Disable and enable to reset peripheral |
| 50 | r.power.write(|w| w.power().disabled()); | 51 | r.power().write(|w| w.set_power(false)); |
| 51 | r.power.write(|w| w.power().enabled()); | 52 | r.power().write(|w| w.set_power(true)); |
| 52 | 53 | ||
| 53 | // Enable 802.15.4 mode | 54 | // Enable 802.15.4 mode |
| 54 | r.mode.write(|w| w.mode().ieee802154_250kbit()); | 55 | r.mode().write(|w| w.set_mode(vals::Mode::IEEE802154_250KBIT)); |
| 55 | // Configure CRC skip address | 56 | // Configure CRC skip address |
| 56 | r.crccnf.write(|w| w.len().two().skipaddr().ieee802154()); | 57 | r.crccnf().write(|w| { |
| 57 | unsafe { | 58 | w.set_len(vals::Len::TWO); |
| 58 | // Configure CRC polynomial and init | 59 | w.set_skipaddr(vals::Skipaddr::IEEE802154); |
| 59 | r.crcpoly.write(|w| w.crcpoly().bits(0x0001_1021)); | 60 | }); |
| 60 | r.crcinit.write(|w| w.crcinit().bits(0)); | 61 | // Configure CRC polynomial and init |
| 61 | r.pcnf0.write(|w| { | 62 | r.crcpoly().write(|w| w.set_crcpoly(0x0001_1021)); |
| 62 | // 8-bit on air length | 63 | r.crcinit().write(|w| w.set_crcinit(0)); |
| 63 | w.lflen() | 64 | r.pcnf0().write(|w| { |
| 64 | .bits(8) | 65 | // 8-bit on air length |
| 65 | // Zero bytes S0 field length | 66 | w.set_lflen(8); |
| 66 | .s0len() | 67 | // Zero bytes S0 field length |
| 67 | .clear_bit() | 68 | w.set_s0len(false); |
| 68 | // Zero bytes S1 field length | 69 | // Zero bytes S1 field length |
| 69 | .s1len() | 70 | w.set_s1len(0); |
| 70 | .bits(0) | 71 | // Do not include S1 field in RAM if S1 length > 0 |
| 71 | // Do not include S1 field in RAM if S1 length > 0 | 72 | w.set_s1incl(vals::S1incl::AUTOMATIC); |
| 72 | .s1incl() | 73 | // Zero code Indicator length |
| 73 | .clear_bit() | 74 | w.set_cilen(0); |
| 74 | // Zero code Indicator length | 75 | // 32-bit zero preamble |
| 75 | .cilen() | 76 | w.set_plen(vals::Plen::_32BIT_ZERO); |
| 76 | .bits(0) | 77 | // Include CRC in length |
| 77 | // 32-bit zero preamble | 78 | w.set_crcinc(vals::Crcinc::INCLUDE); |
| 78 | .plen() | 79 | }); |
| 79 | ._32bit_zero() | 80 | r.pcnf1().write(|w| { |
| 80 | // Include CRC in length | 81 | // Maximum packet length |
| 81 | .crcinc() | 82 | w.set_maxlen(Packet::MAX_PSDU_LEN); |
| 82 | .include() | 83 | // Zero static length |
| 83 | }); | 84 | w.set_statlen(0); |
| 84 | r.pcnf1.write(|w| { | 85 | // Zero base address length |
| 85 | // Maximum packet length | 86 | w.set_balen(0); |
| 86 | w.maxlen() | 87 | // Little-endian |
| 87 | .bits(Packet::MAX_PSDU_LEN) | 88 | w.set_endian(vals::Endian::LITTLE); |
| 88 | // Zero static length | 89 | // Disable packet whitening |
| 89 | .statlen() | 90 | w.set_whiteen(false); |
| 90 | .bits(0) | 91 | }); |
| 91 | // Zero base address length | ||
| 92 | .balen() | ||
| 93 | .bits(0) | ||
| 94 | // Little-endian | ||
| 95 | .endian() | ||
| 96 | .clear_bit() | ||
| 97 | // Disable packet whitening | ||
| 98 | .whiteen() | ||
| 99 | .clear_bit() | ||
| 100 | }); | ||
| 101 | } | ||
| 102 | 92 | ||
| 103 | // Enable NVIC interrupt | 93 | // Enable NVIC interrupt |
| 104 | T::Interrupt::unpend(); | 94 | T::Interrupt::unpend(); |
| @@ -125,8 +115,10 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 125 | } | 115 | } |
| 126 | let frequency_offset = (channel - 10) * 5; | 116 | let frequency_offset = (channel - 10) * 5; |
| 127 | self.needs_enable = true; | 117 | self.needs_enable = true; |
| 128 | r.frequency | 118 | r.frequency().write(|w| { |
| 129 | .write(|w| unsafe { w.frequency().bits(frequency_offset).map().default() }); | 119 | w.set_frequency(frequency_offset); |
| 120 | w.set_map(vals::Map::DEFAULT); | ||
| 121 | }); | ||
| 130 | } | 122 | } |
| 131 | 123 | ||
| 132 | /// Changes the Clear Channel Assessment method | 124 | /// Changes the Clear Channel Assessment method |
| @@ -134,12 +126,14 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 134 | let r = T::regs(); | 126 | let r = T::regs(); |
| 135 | self.needs_enable = true; | 127 | self.needs_enable = true; |
| 136 | match cca { | 128 | match cca { |
| 137 | Cca::CarrierSense => r.ccactrl.write(|w| w.ccamode().carrier_mode()), | 129 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), |
| 138 | Cca::EnergyDetection { ed_threshold } => { | 130 | Cca::EnergyDetection { ed_threshold } => { |
| 139 | // "[ED] is enabled by first configuring the field CCAMODE=EdMode in CCACTRL | 131 | // "[ED] is enabled by first configuring the field CCAMODE=EdMode in CCACTRL |
| 140 | // and writing the CCAEDTHRES field to a chosen value." | 132 | // and writing the CCAEDTHRES field to a chosen value." |
| 141 | r.ccactrl | 133 | r.ccactrl().write(|w| { |
| 142 | .write(|w| unsafe { w.ccamode().ed_mode().ccaedthres().bits(ed_threshold) }); | 134 | w.set_ccamode(vals::Ccamode::ED_MODE); |
| 135 | w.set_ccaedthres(ed_threshold); | ||
| 136 | }); | ||
| 143 | } | 137 | } |
| 144 | } | 138 | } |
| 145 | } | 139 | } |
| @@ -147,13 +141,13 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 147 | /// Changes the Start of Frame Delimiter (SFD) | 141 | /// Changes the Start of Frame Delimiter (SFD) |
| 148 | pub fn set_sfd(&mut self, sfd: u8) { | 142 | pub fn set_sfd(&mut self, sfd: u8) { |
| 149 | let r = T::regs(); | 143 | let r = T::regs(); |
| 150 | r.sfd.write(|w| unsafe { w.sfd().bits(sfd) }); | 144 | r.sfd().write(|w| w.set_sfd(sfd)); |
| 151 | } | 145 | } |
| 152 | 146 | ||
| 153 | /// Clear interrupts | 147 | /// Clear interrupts |
| 154 | pub fn clear_all_interrupts(&mut self) { | 148 | pub fn clear_all_interrupts(&mut self) { |
| 155 | let r = T::regs(); | 149 | let r = T::regs(); |
| 156 | r.intenclr.write(|w| unsafe { w.bits(0xffff_ffff) }); | 150 | r.intenclr().write(|w| w.0 = 0xffff_ffff); |
| 157 | } | 151 | } |
| 158 | 152 | ||
| 159 | /// Changes the radio transmission power | 153 | /// Changes the radio transmission power |
| @@ -163,43 +157,43 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 163 | 157 | ||
| 164 | let tx_power: TxPower = match power { | 158 | let tx_power: TxPower = match power { |
| 165 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] | 159 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] |
| 166 | 8 => TxPower::POS8D_BM, | 160 | 8 => TxPower::POS8_DBM, |
| 167 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] | 161 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] |
| 168 | 7 => TxPower::POS7D_BM, | 162 | 7 => TxPower::POS7_DBM, |
| 169 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] | 163 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] |
| 170 | 6 => TxPower::POS6D_BM, | 164 | 6 => TxPower::POS6_DBM, |
| 171 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] | 165 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] |
| 172 | 5 => TxPower::POS5D_BM, | 166 | 5 => TxPower::POS5_DBM, |
| 173 | #[cfg(not(feature = "_nrf5340-net"))] | 167 | #[cfg(not(feature = "_nrf5340-net"))] |
| 174 | 4 => TxPower::POS4D_BM, | 168 | 4 => TxPower::POS4_DBM, |
| 175 | #[cfg(not(feature = "_nrf5340-net"))] | 169 | #[cfg(not(feature = "_nrf5340-net"))] |
| 176 | 3 => TxPower::POS3D_BM, | 170 | 3 => TxPower::POS3_DBM, |
| 177 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] | 171 | #[cfg(not(any(feature = "nrf52811", feature = "_nrf5340-net")))] |
| 178 | 2 => TxPower::POS2D_BM, | 172 | 2 => TxPower::POS2_DBM, |
| 179 | 0 => TxPower::_0D_BM, | 173 | 0 => TxPower::_0_DBM, |
| 180 | #[cfg(feature = "_nrf5340-net")] | 174 | #[cfg(feature = "_nrf5340-net")] |
| 181 | -1 => TxPower::NEG1D_BM, | 175 | -1 => TxPower::NEG1_DBM, |
| 182 | #[cfg(feature = "_nrf5340-net")] | 176 | #[cfg(feature = "_nrf5340-net")] |
| 183 | -2 => TxPower::NEG2D_BM, | 177 | -2 => TxPower::NEG2_DBM, |
| 184 | #[cfg(feature = "_nrf5340-net")] | 178 | #[cfg(feature = "_nrf5340-net")] |
| 185 | -3 => TxPower::NEG3D_BM, | 179 | -3 => TxPower::NEG3_DBM, |
| 186 | -4 => TxPower::NEG4D_BM, | 180 | -4 => TxPower::NEG4_DBM, |
| 187 | #[cfg(feature = "_nrf5340-net")] | 181 | #[cfg(feature = "_nrf5340-net")] |
| 188 | -5 => TxPower::NEG5D_BM, | 182 | -5 => TxPower::NEG5_DBM, |
| 189 | #[cfg(feature = "_nrf5340-net")] | 183 | #[cfg(feature = "_nrf5340-net")] |
| 190 | -6 => TxPower::NEG6D_BM, | 184 | -6 => TxPower::NEG6_DBM, |
| 191 | #[cfg(feature = "_nrf5340-net")] | 185 | #[cfg(feature = "_nrf5340-net")] |
| 192 | -7 => TxPower::NEG7D_BM, | 186 | -7 => TxPower::NEG7_DBM, |
| 193 | -8 => TxPower::NEG8D_BM, | 187 | -8 => TxPower::NEG8_DBM, |
| 194 | -12 => TxPower::NEG12D_BM, | 188 | -12 => TxPower::NEG12_DBM, |
| 195 | -16 => TxPower::NEG16D_BM, | 189 | -16 => TxPower::NEG16_DBM, |
| 196 | -20 => TxPower::NEG20D_BM, | 190 | -20 => TxPower::NEG20_DBM, |
| 197 | -30 => TxPower::NEG30D_BM, | 191 | -30 => TxPower::NEG30_DBM, |
| 198 | -40 => TxPower::NEG40D_BM, | 192 | -40 => TxPower::NEG40_DBM, |
| 199 | _ => panic!("Invalid transmission power value"), | 193 | _ => panic!("Invalid transmission power value"), |
| 200 | }; | 194 | }; |
| 201 | 195 | ||
| 202 | r.txpower.write(|w| w.txpower().variant(tx_power)); | 196 | r.txpower().write(|w| w.set_txpower(tx_power)); |
| 203 | } | 197 | } |
| 204 | 198 | ||
| 205 | /// Waits until the radio state matches the given `state` | 199 | /// Waits until the radio state matches the given `state` |
| @@ -221,7 +215,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 221 | RadioState::DISABLED => return, | 215 | RadioState::DISABLED => return, |
| 222 | // idle or ramping up | 216 | // idle or ramping up |
| 223 | RadioState::RX_RU | RadioState::RX_IDLE | RadioState::TX_RU | RadioState::TX_IDLE => { | 217 | RadioState::RX_RU | RadioState::RX_IDLE | RadioState::TX_RU | RadioState::TX_IDLE => { |
| 224 | r.tasks_disable.write(|w| w.tasks_disable().set_bit()); | 218 | r.tasks_disable().write_value(1); |
| 225 | self.wait_for_radio_state(RadioState::DISABLED); | 219 | self.wait_for_radio_state(RadioState::DISABLED); |
| 226 | return; | 220 | return; |
| 227 | } | 221 | } |
| @@ -232,29 +226,30 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 232 | } | 226 | } |
| 233 | // cancel ongoing transfer or ongoing CCA | 227 | // cancel ongoing transfer or ongoing CCA |
| 234 | RadioState::RX => { | 228 | RadioState::RX => { |
| 235 | r.tasks_ccastop.write(|w| w.tasks_ccastop().set_bit()); | 229 | r.tasks_ccastop().write_value(1); |
| 236 | r.tasks_stop.write(|w| w.tasks_stop().set_bit()); | 230 | r.tasks_stop().write_value(1); |
| 237 | self.wait_for_radio_state(RadioState::RX_IDLE); | 231 | self.wait_for_radio_state(RadioState::RX_IDLE); |
| 238 | } | 232 | } |
| 239 | RadioState::TX => { | 233 | RadioState::TX => { |
| 240 | r.tasks_stop.write(|w| w.tasks_stop().set_bit()); | 234 | r.tasks_stop().write_value(1); |
| 241 | self.wait_for_radio_state(RadioState::TX_IDLE); | 235 | self.wait_for_radio_state(RadioState::TX_IDLE); |
| 242 | } | 236 | } |
| 237 | _ => unreachable!(), | ||
| 243 | } | 238 | } |
| 244 | } | 239 | } |
| 245 | } | 240 | } |
| 246 | 241 | ||
| 247 | fn set_buffer(&mut self, buffer: &[u8]) { | 242 | fn set_buffer(&mut self, buffer: &[u8]) { |
| 248 | let r = T::regs(); | 243 | let r = T::regs(); |
| 249 | r.packetptr.write(|w| unsafe { w.bits(buffer.as_ptr() as u32) }); | 244 | r.packetptr().write_value(buffer.as_ptr() as u32); |
| 250 | } | 245 | } |
| 251 | 246 | ||
| 252 | /// Moves the radio to the RXIDLE state | 247 | /// Moves the radio to the RXIDLE state |
| 253 | fn receive_prepare(&mut self) { | 248 | fn receive_prepare(&mut self) { |
| 254 | // clear related events | 249 | // clear related events |
| 255 | T::regs().events_ccabusy.reset(); | 250 | T::regs().events_ccabusy().write_value(0); |
| 256 | T::regs().events_phyend.reset(); | 251 | T::regs().events_phyend().write_value(0); |
| 257 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RX_IDLE | 252 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE |
| 258 | let disable = match self.state() { | 253 | let disable = match self.state() { |
| 259 | RadioState::DISABLED => false, | 254 | RadioState::DISABLED => false, |
| 260 | RadioState::RX_IDLE => self.needs_enable, | 255 | RadioState::RX_IDLE => self.needs_enable, |
| @@ -279,7 +274,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 279 | // The radio goes through following states when receiving a 802.15.4 packet | 274 | // The radio goes through following states when receiving a 802.15.4 packet |
| 280 | // | 275 | // |
| 281 | // enable RX → ramp up RX → RX idle → Receive → end (PHYEND) | 276 | // enable RX → ramp up RX → RX idle → Receive → end (PHYEND) |
| 282 | r.shorts.write(|w| w.rxready_start().enabled()); | 277 | r.shorts().write(|w| w.set_rxready_start(true)); |
| 283 | 278 | ||
| 284 | // set up RX buffer | 279 | // set up RX buffer |
| 285 | self.set_buffer(packet.buffer.as_mut()); | 280 | self.set_buffer(packet.buffer.as_mut()); |
| @@ -289,17 +284,17 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 289 | 284 | ||
| 290 | match self.state() { | 285 | match self.state() { |
| 291 | // Re-start receiver | 286 | // Re-start receiver |
| 292 | RadioState::RX_IDLE => r.tasks_start.write(|w| w.tasks_start().set_bit()), | 287 | RadioState::RX_IDLE => r.tasks_start().write_value(1), |
| 293 | // Enable receiver | 288 | // Enable receiver |
| 294 | _ => r.tasks_rxen.write(|w| w.tasks_rxen().set_bit()), | 289 | _ => r.tasks_rxen().write_value(1), |
| 295 | } | 290 | } |
| 296 | } | 291 | } |
| 297 | 292 | ||
| 298 | /// Cancel receiving packet | 293 | /// Cancel receiving packet |
| 299 | fn receive_cancel() { | 294 | fn receive_cancel() { |
| 300 | let r = T::regs(); | 295 | let r = T::regs(); |
| 301 | r.shorts.reset(); | 296 | r.shorts().write(|_| {}); |
| 302 | r.tasks_stop.write(|w| w.tasks_stop().set_bit()); | 297 | r.tasks_stop().write_value(1); |
| 303 | loop { | 298 | loop { |
| 304 | match state(r) { | 299 | match state(r) { |
| 305 | RadioState::DISABLED | RadioState::RX_IDLE => break, | 300 | RadioState::DISABLED | RadioState::RX_IDLE => break, |
| @@ -329,12 +324,12 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 329 | core::future::poll_fn(|cx| { | 324 | core::future::poll_fn(|cx| { |
| 330 | s.event_waker.register(cx.waker()); | 325 | s.event_waker.register(cx.waker()); |
| 331 | 326 | ||
| 332 | if r.events_phyend.read().events_phyend().bit_is_set() { | 327 | if r.events_phyend().read() != 0 { |
| 333 | r.events_phyend.reset(); | 328 | r.events_phyend().write_value(0); |
| 334 | trace!("RX done poll"); | 329 | trace!("RX done poll"); |
| 335 | return Poll::Ready(()); | 330 | return Poll::Ready(()); |
| 336 | } else { | 331 | } else { |
| 337 | r.intenset.write(|w| w.phyend().set()); | 332 | r.intenset().write(|w| w.set_phyend(true)); |
| 338 | }; | 333 | }; |
| 339 | 334 | ||
| 340 | Poll::Pending | 335 | Poll::Pending |
| @@ -344,8 +339,8 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 344 | dma_end_fence(); | 339 | dma_end_fence(); |
| 345 | dropper.defuse(); | 340 | dropper.defuse(); |
| 346 | 341 | ||
| 347 | let crc = r.rxcrc.read().rxcrc().bits() as u16; | 342 | let crc = r.rxcrc().read().rxcrc() as u16; |
| 348 | if r.crcstatus.read().crcstatus().bit_is_set() { | 343 | if r.crcstatus().read().crcstatus() == vals::Crcstatus::CRCOK { |
| 349 | Ok(()) | 344 | Ok(()) |
| 350 | } else { | 345 | } else { |
| 351 | Err(Error::CrcFailed(crc)) | 346 | Err(Error::CrcFailed(crc)) |
| @@ -387,17 +382,12 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 387 | // CCA idle → enable TX → start TX → TX → end (PHYEND) → disabled | 382 | // CCA idle → enable TX → start TX → TX → end (PHYEND) → disabled |
| 388 | // | 383 | // |
| 389 | // CCA might end up in the event CCABUSY in which there will be no transmission | 384 | // CCA might end up in the event CCABUSY in which there will be no transmission |
| 390 | r.shorts.write(|w| { | 385 | r.shorts().write(|w| { |
| 391 | w.rxready_ccastart() | 386 | w.set_rxready_ccastart(true); |
| 392 | .enabled() | 387 | w.set_ccaidle_txen(true); |
| 393 | .ccaidle_txen() | 388 | w.set_txready_start(true); |
| 394 | .enabled() | 389 | w.set_ccabusy_disable(true); |
| 395 | .txready_start() | 390 | w.set_phyend_disable(true); |
| 396 | .enabled() | ||
| 397 | .ccabusy_disable() | ||
| 398 | .enabled() | ||
| 399 | .phyend_disable() | ||
| 400 | .enabled() | ||
| 401 | }); | 391 | }); |
| 402 | 392 | ||
| 403 | // Set transmission buffer | 393 | // Set transmission buffer |
| @@ -410,27 +400,30 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 410 | 400 | ||
| 411 | match self.state() { | 401 | match self.state() { |
| 412 | // Re-start receiver | 402 | // Re-start receiver |
| 413 | RadioState::RX_IDLE => r.tasks_ccastart.write(|w| w.tasks_ccastart().set_bit()), | 403 | RadioState::RX_IDLE => r.tasks_ccastart().write_value(1), |
| 414 | // Enable receiver | 404 | // Enable receiver |
| 415 | _ => r.tasks_rxen.write(|w| w.tasks_rxen().set_bit()), | 405 | _ => r.tasks_rxen().write_value(1), |
| 416 | } | 406 | } |
| 417 | 407 | ||
| 418 | self.clear_all_interrupts(); | 408 | self.clear_all_interrupts(); |
| 419 | let result = core::future::poll_fn(|cx| { | 409 | let result = core::future::poll_fn(|cx| { |
| 420 | s.event_waker.register(cx.waker()); | 410 | s.event_waker.register(cx.waker()); |
| 421 | 411 | ||
| 422 | if r.events_phyend.read().events_phyend().bit_is_set() { | 412 | if r.events_phyend().read() != 0 { |
| 423 | r.events_phyend.reset(); | 413 | r.events_phyend().write_value(0); |
| 424 | r.events_ccabusy.reset(); | 414 | r.events_ccabusy().write_value(0); |
| 425 | trace!("TX done poll"); | 415 | trace!("TX done poll"); |
| 426 | return Poll::Ready(TransmitResult::Success); | 416 | return Poll::Ready(TransmitResult::Success); |
| 427 | } else if r.events_ccabusy.read().events_ccabusy().bit_is_set() { | 417 | } else if r.events_ccabusy().read() != 0 { |
| 428 | r.events_ccabusy.reset(); | 418 | r.events_ccabusy().write_value(0); |
| 429 | trace!("TX no CCA"); | 419 | trace!("TX no CCA"); |
| 430 | return Poll::Ready(TransmitResult::ChannelInUse); | 420 | return Poll::Ready(TransmitResult::ChannelInUse); |
| 431 | } | 421 | } |
| 432 | 422 | ||
| 433 | r.intenset.write(|w| w.phyend().set().ccabusy().set()); | 423 | r.intenset().write(|w| { |
| 424 | w.set_phyend(true); | ||
| 425 | w.set_ccabusy(true); | ||
| 426 | }); | ||
| 434 | 427 | ||
| 435 | Poll::Pending | 428 | Poll::Pending |
| 436 | }) | 429 | }) |
diff --git a/embassy-nrf/src/radio/mod.rs b/embassy-nrf/src/radio/mod.rs index 8edca1df2..251f37d3d 100644 --- a/embassy-nrf/src/radio/mod.rs +++ b/embassy-nrf/src/radio/mod.rs | |||
| @@ -20,8 +20,8 @@ pub mod ieee802154; | |||
| 20 | use core::marker::PhantomData; | 20 | use core::marker::PhantomData; |
| 21 | 21 | ||
| 22 | use embassy_sync::waitqueue::AtomicWaker; | 22 | use embassy_sync::waitqueue::AtomicWaker; |
| 23 | use pac::radio::state::STATE_A as RadioState; | 23 | use pac::radio::vals::State as RadioState; |
| 24 | pub use pac::radio::txpower::TXPOWER_A as TxPower; | 24 | pub use pac::radio::vals::Txpower as TxPower; |
| 25 | 25 | ||
| 26 | use crate::{interrupt, pac, Peripheral}; | 26 | use crate::{interrupt, pac, Peripheral}; |
| 27 | 27 | ||
| @@ -52,7 +52,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 52 | let r = T::regs(); | 52 | let r = T::regs(); |
| 53 | let s = T::state(); | 53 | let s = T::state(); |
| 54 | // clear all interrupts | 54 | // clear all interrupts |
| 55 | r.intenclr.write(|w| w.bits(0xffff_ffff)); | 55 | r.intenclr().write(|w| w.0 = 0xffff_ffff); |
| 56 | s.event_waker.wake(); | 56 | s.event_waker.wake(); |
| 57 | } | 57 | } |
| 58 | } | 58 | } |
| @@ -70,15 +70,15 @@ impl State { | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | pub(crate) trait SealedInstance { | 72 | pub(crate) trait SealedInstance { |
| 73 | fn regs() -> &'static crate::pac::radio::RegisterBlock; | 73 | fn regs() -> crate::pac::radio::Radio; |
| 74 | fn state() -> &'static State; | 74 | fn state() -> &'static State; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | macro_rules! impl_radio { | 77 | macro_rules! impl_radio { |
| 78 | ($type:ident, $pac_type:ident, $irq:ident) => { | 78 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 79 | impl crate::radio::SealedInstance for peripherals::$type { | 79 | impl crate::radio::SealedInstance for peripherals::$type { |
| 80 | fn regs() -> &'static pac::radio::RegisterBlock { | 80 | fn regs() -> crate::pac::radio::Radio { |
| 81 | unsafe { &*pac::$pac_type::ptr() } | 81 | pac::$pac_type |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | fn state() -> &'static crate::radio::State { | 84 | fn state() -> &'static crate::radio::State { |
| @@ -100,9 +100,6 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | /// Get the state of the radio | 102 | /// Get the state of the radio |
| 103 | pub(crate) fn state(radio: &pac::radio::RegisterBlock) -> RadioState { | 103 | pub(crate) fn state(radio: pac::radio::Radio) -> RadioState { |
| 104 | match radio.state.read().state().variant() { | 104 | radio.state().read().state() |
| 105 | Some(state) => state, | ||
| 106 | None => unreachable!(), | ||
| 107 | } | ||
| 108 | } | 105 | } |
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs index ff61e08f3..7a98ab2fb 100644 --- a/embassy-nrf/src/rng.rs +++ b/embassy-nrf/src/rng.rs | |||
| @@ -14,7 +14,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 14 | use embassy_sync::waitqueue::WakerRegistration; | 14 | use embassy_sync::waitqueue::WakerRegistration; |
| 15 | 15 | ||
| 16 | use crate::interrupt::typelevel::Interrupt; | 16 | use crate::interrupt::typelevel::Interrupt; |
| 17 | use crate::{interrupt, Peripheral}; | 17 | use crate::{interrupt, pac, Peripheral}; |
| 18 | 18 | ||
| 19 | /// Interrupt handler. | 19 | /// Interrupt handler. |
| 20 | pub struct InterruptHandler<T: Instance> { | 20 | pub struct InterruptHandler<T: Instance> { |
| @@ -26,7 +26,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 26 | let r = T::regs(); | 26 | let r = T::regs(); |
| 27 | 27 | ||
| 28 | // Clear the event. | 28 | // Clear the event. |
| 29 | r.events_valrdy.reset(); | 29 | r.events_valrdy().write_value(0); |
| 30 | 30 | ||
| 31 | // Mutate the slice within a critical section, | 31 | // Mutate the slice within a critical section, |
| 32 | // so that the future isn't dropped in between us loading the pointer and actually dereferencing it. | 32 | // so that the future isn't dropped in between us loading the pointer and actually dereferencing it. |
| @@ -40,7 +40,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 40 | // The safety contract of `Rng::new` means that the future can't have been dropped | 40 | // The safety contract of `Rng::new` means that the future can't have been dropped |
| 41 | // without calling its destructor. | 41 | // without calling its destructor. |
| 42 | unsafe { | 42 | unsafe { |
| 43 | *state.ptr = r.value.read().value().bits(); | 43 | *state.ptr = r.value().read().value(); |
| 44 | state.ptr = state.ptr.add(1); | 44 | state.ptr = state.ptr.add(1); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| @@ -84,19 +84,19 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | fn stop(&self) { | 86 | fn stop(&self) { |
| 87 | T::regs().tasks_stop.write(|w| unsafe { w.bits(1) }) | 87 | T::regs().tasks_stop().write_value(1) |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | fn start(&self) { | 90 | fn start(&self) { |
| 91 | T::regs().tasks_start.write(|w| unsafe { w.bits(1) }) | 91 | T::regs().tasks_start().write_value(1) |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | fn enable_irq(&self) { | 94 | fn enable_irq(&self) { |
| 95 | T::regs().intenset.write(|w| w.valrdy().set()); | 95 | T::regs().intenset().write(|w| w.set_valrdy(true)); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | fn disable_irq(&self) { | 98 | fn disable_irq(&self) { |
| 99 | T::regs().intenclr.write(|w| w.valrdy().clear()); | 99 | T::regs().intenclr().write(|w| w.set_valrdy(true)); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | /// Enable or disable the RNG's bias correction. | 102 | /// Enable or disable the RNG's bias correction. |
| @@ -106,7 +106,7 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 106 | /// | 106 | /// |
| 107 | /// Defaults to disabled. | 107 | /// Defaults to disabled. |
| 108 | pub fn set_bias_correction(&self, enable: bool) { | 108 | pub fn set_bias_correction(&self, enable: bool) { |
| 109 | T::regs().config.write(|w| w.dercen().bit(enable)) | 109 | T::regs().config().write(|w| w.set_dercen(enable)) |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | /// Fill the buffer with random bytes. | 112 | /// Fill the buffer with random bytes. |
| @@ -162,9 +162,9 @@ impl<'d, T: Instance> Rng<'d, T> { | |||
| 162 | 162 | ||
| 163 | for byte in dest.iter_mut() { | 163 | for byte in dest.iter_mut() { |
| 164 | let regs = T::regs(); | 164 | let regs = T::regs(); |
| 165 | while regs.events_valrdy.read().bits() == 0 {} | 165 | while regs.events_valrdy().read() == 0 {} |
| 166 | regs.events_valrdy.reset(); | 166 | regs.events_valrdy().write_value(0); |
| 167 | *byte = regs.value.read().value().bits(); | 167 | *byte = regs.value().read().value(); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | self.stop(); | 170 | self.stop(); |
| @@ -244,7 +244,7 @@ impl InnerState { | |||
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | pub(crate) trait SealedInstance { | 246 | pub(crate) trait SealedInstance { |
| 247 | fn regs() -> &'static crate::pac::rng::RegisterBlock; | 247 | fn regs() -> pac::rng::Rng; |
| 248 | fn state() -> &'static State; | 248 | fn state() -> &'static State; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| @@ -258,8 +258,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 258 | macro_rules! impl_rng { | 258 | macro_rules! impl_rng { |
| 259 | ($type:ident, $pac_type:ident, $irq:ident) => { | 259 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 260 | impl crate::rng::SealedInstance for peripherals::$type { | 260 | impl crate::rng::SealedInstance for peripherals::$type { |
| 261 | fn regs() -> &'static crate::pac::rng::RegisterBlock { | 261 | fn regs() -> crate::pac::rng::Rng { |
| 262 | unsafe { &*pac::$pac_type::ptr() } | 262 | pac::$pac_type |
| 263 | } | 263 | } |
| 264 | fn state() -> &'static crate::rng::State { | 264 | fn state() -> &'static crate::rng::State { |
| 265 | static STATE: crate::rng::State = crate::rng::State::new(); | 265 | static STATE: crate::rng::State = crate::rng::State::new(); |
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index bbfa9b3b9..70bda9f70 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -9,14 +9,10 @@ use core::task::Poll; | |||
| 9 | use embassy_hal_internal::drop::OnDrop; | 9 | use embassy_hal_internal::drop::OnDrop; |
| 10 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | use pac::{saadc, SAADC}; | 12 | pub(crate) use vals::Psel as InputChannel; |
| 13 | use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; | ||
| 14 | // We treat the positive and negative channels with the same enum values to keep our type tidy and given they are the same | ||
| 15 | pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel; | ||
| 16 | use saadc::oversample::OVERSAMPLE_A; | ||
| 17 | use saadc::resolution::VAL_A; | ||
| 18 | 13 | ||
| 19 | use crate::interrupt::InterruptExt; | 14 | use crate::interrupt::InterruptExt; |
| 15 | use crate::pac::saadc::vals; | ||
| 20 | use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; | 16 | use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; |
| 21 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; | 17 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; |
| 22 | use crate::{interrupt, pac, peripherals, Peripheral}; | 18 | use crate::{interrupt, pac, peripherals, Peripheral}; |
| @@ -34,20 +30,20 @@ pub struct InterruptHandler { | |||
| 34 | 30 | ||
| 35 | impl interrupt::typelevel::Handler<interrupt::typelevel::SAADC> for InterruptHandler { | 31 | impl interrupt::typelevel::Handler<interrupt::typelevel::SAADC> for InterruptHandler { |
| 36 | unsafe fn on_interrupt() { | 32 | unsafe fn on_interrupt() { |
| 37 | let r = unsafe { &*SAADC::ptr() }; | 33 | let r = pac::SAADC; |
| 38 | 34 | ||
| 39 | if r.events_calibratedone.read().bits() != 0 { | 35 | if r.events_calibratedone().read() != 0 { |
| 40 | r.intenclr.write(|w| w.calibratedone().clear()); | 36 | r.intenclr().write(|w| w.set_calibratedone(true)); |
| 41 | WAKER.wake(); | 37 | WAKER.wake(); |
| 42 | } | 38 | } |
| 43 | 39 | ||
| 44 | if r.events_end.read().bits() != 0 { | 40 | if r.events_end().read() != 0 { |
| 45 | r.intenclr.write(|w| w.end().clear()); | 41 | r.intenclr().write(|w| w.set_end(true)); |
| 46 | WAKER.wake(); | 42 | WAKER.wake(); |
| 47 | } | 43 | } |
| 48 | 44 | ||
| 49 | if r.events_started.read().bits() != 0 { | 45 | if r.events_started().read() != 0 { |
| 50 | r.intenclr.write(|w| w.started().clear()); | 46 | r.intenclr().write(|w| w.set_started(true)); |
| 51 | WAKER.wake(); | 47 | WAKER.wake(); |
| 52 | } | 48 | } |
| 53 | } | 49 | } |
| @@ -150,44 +146,36 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 150 | ) -> Self { | 146 | ) -> Self { |
| 151 | into_ref!(saadc); | 147 | into_ref!(saadc); |
| 152 | 148 | ||
| 153 | let r = unsafe { &*SAADC::ptr() }; | 149 | let r = pac::SAADC; |
| 154 | 150 | ||
| 155 | let Config { resolution, oversample } = config; | 151 | let Config { resolution, oversample } = config; |
| 156 | 152 | ||
| 157 | // Configure channels | 153 | // Configure channels |
| 158 | r.enable.write(|w| w.enable().enabled()); | 154 | r.enable().write(|w| w.set_enable(true)); |
| 159 | r.resolution.write(|w| w.val().variant(resolution.into())); | 155 | r.resolution().write(|w| w.set_val(resolution.into())); |
| 160 | r.oversample.write(|w| w.oversample().variant(oversample.into())); | 156 | r.oversample().write(|w| w.set_oversample(oversample.into())); |
| 161 | 157 | ||
| 162 | for (i, cc) in channel_configs.iter().enumerate() { | 158 | for (i, cc) in channel_configs.iter().enumerate() { |
| 163 | r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel.channel())); | 159 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); |
| 164 | if let Some(n_channel) = &cc.n_channel { | 160 | if let Some(n_channel) = &cc.n_channel { |
| 165 | r.ch[i] | 161 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); |
| 166 | .pseln | ||
| 167 | .write(|w| unsafe { w.pseln().bits(n_channel.channel() as u8) }); | ||
| 168 | } | 162 | } |
| 169 | r.ch[i].config.write(|w| { | 163 | r.ch(i).config().write(|w| { |
| 170 | w.refsel().variant(cc.reference.into()); | 164 | w.set_refsel(cc.reference.into()); |
| 171 | w.gain().variant(cc.gain.into()); | 165 | w.set_gain(cc.gain.into()); |
| 172 | w.tacq().variant(cc.time.into()); | 166 | w.set_tacq(cc.time.into()); |
| 173 | if cc.n_channel.is_none() { | 167 | w.set_mode(match cc.n_channel { |
| 174 | w.mode().se(); | 168 | None => vals::ConfigMode::SE, |
| 175 | } else { | 169 | Some(_) => vals::ConfigMode::DIFF, |
| 176 | w.mode().diff(); | 170 | }); |
| 177 | } | 171 | w.set_resp(cc.resistor.into()); |
| 178 | w.resp().variant(cc.resistor.into()); | 172 | w.set_resn(vals::Resn::BYPASS); |
| 179 | w.resn().bypass(); | 173 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); |
| 180 | if !matches!(oversample, Oversample::BYPASS) { | ||
| 181 | w.burst().enabled(); | ||
| 182 | } else { | ||
| 183 | w.burst().disabled(); | ||
| 184 | } | ||
| 185 | w | ||
| 186 | }); | 174 | }); |
| 187 | } | 175 | } |
| 188 | 176 | ||
| 189 | // Disable all events interrupts | 177 | // Disable all events interrupts |
| 190 | r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); | 178 | r.intenclr().write(|w| w.0 = 0x003F_FFFF); |
| 191 | 179 | ||
| 192 | interrupt::SAADC.unpend(); | 180 | interrupt::SAADC.unpend(); |
| 193 | unsafe { interrupt::SAADC.enable() }; | 181 | unsafe { interrupt::SAADC.enable() }; |
| @@ -195,8 +183,8 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 195 | Self { _p: saadc } | 183 | Self { _p: saadc } |
| 196 | } | 184 | } |
| 197 | 185 | ||
| 198 | fn regs() -> &'static saadc::RegisterBlock { | 186 | fn regs() -> pac::saadc::Saadc { |
| 199 | unsafe { &*SAADC::ptr() } | 187 | pac::SAADC |
| 200 | } | 188 | } |
| 201 | 189 | ||
| 202 | /// Perform SAADC calibration. Completes when done. | 190 | /// Perform SAADC calibration. Completes when done. |
| @@ -204,13 +192,13 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 204 | let r = Self::regs(); | 192 | let r = Self::regs(); |
| 205 | 193 | ||
| 206 | // Reset and enable the end event | 194 | // Reset and enable the end event |
| 207 | r.events_calibratedone.reset(); | 195 | r.events_calibratedone().write_value(0); |
| 208 | r.intenset.write(|w| w.calibratedone().set()); | 196 | r.intenset().write(|w| w.set_calibratedone(true)); |
| 209 | 197 | ||
| 210 | // Order is important | 198 | // Order is important |
| 211 | compiler_fence(Ordering::SeqCst); | 199 | compiler_fence(Ordering::SeqCst); |
| 212 | 200 | ||
| 213 | r.tasks_calibrateoffset.write(|w| unsafe { w.bits(1) }); | 201 | r.tasks_calibrateoffset().write_value(1); |
| 214 | 202 | ||
| 215 | // Wait for 'calibratedone' event. | 203 | // Wait for 'calibratedone' event. |
| 216 | poll_fn(|cx| { | 204 | poll_fn(|cx| { |
| @@ -218,8 +206,8 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 218 | 206 | ||
| 219 | WAKER.register(cx.waker()); | 207 | WAKER.register(cx.waker()); |
| 220 | 208 | ||
| 221 | if r.events_calibratedone.read().bits() != 0 { | 209 | if r.events_calibratedone().read() != 0 { |
| 222 | r.events_calibratedone.reset(); | 210 | r.events_calibratedone().write_value(0); |
| 223 | return Poll::Ready(()); | 211 | return Poll::Ready(()); |
| 224 | } | 212 | } |
| 225 | 213 | ||
| @@ -239,19 +227,19 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 239 | let r = Self::regs(); | 227 | let r = Self::regs(); |
| 240 | 228 | ||
| 241 | // Set up the DMA | 229 | // Set up the DMA |
| 242 | r.result.ptr.write(|w| unsafe { w.ptr().bits(buf.as_mut_ptr() as u32) }); | 230 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); |
| 243 | r.result.maxcnt.write(|w| unsafe { w.maxcnt().bits(N as _) }); | 231 | r.result().maxcnt().write(|w| w.set_maxcnt(N as _)); |
| 244 | 232 | ||
| 245 | // Reset and enable the end event | 233 | // Reset and enable the end event |
| 246 | r.events_end.reset(); | 234 | r.events_end().write_value(0); |
| 247 | r.intenset.write(|w| w.end().set()); | 235 | r.intenset().write(|w| w.set_end(true)); |
| 248 | 236 | ||
| 249 | // Don't reorder the ADC start event before the previous writes. Hopefully self | 237 | // Don't reorder the ADC start event before the previous writes. Hopefully self |
| 250 | // wouldn't happen anyway. | 238 | // wouldn't happen anyway. |
| 251 | compiler_fence(Ordering::SeqCst); | 239 | compiler_fence(Ordering::SeqCst); |
| 252 | 240 | ||
| 253 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 241 | r.tasks_start().write_value(1); |
| 254 | r.tasks_sample.write(|w| unsafe { w.bits(1) }); | 242 | r.tasks_sample().write_value(1); |
| 255 | 243 | ||
| 256 | // Wait for 'end' event. | 244 | // Wait for 'end' event. |
| 257 | poll_fn(|cx| { | 245 | poll_fn(|cx| { |
| @@ -259,8 +247,8 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 259 | 247 | ||
| 260 | WAKER.register(cx.waker()); | 248 | WAKER.register(cx.waker()); |
| 261 | 249 | ||
| 262 | if r.events_end.read().bits() != 0 { | 250 | if r.events_end().read() != 0 { |
| 263 | r.events_end.reset(); | 251 | r.events_end().write_value(0); |
| 264 | return Poll::Ready(()); | 252 | return Poll::Ready(()); |
| 265 | } | 253 | } |
| 266 | 254 | ||
| @@ -311,8 +299,11 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 311 | // We want the task start to effectively short with the last one ending so | 299 | // We want the task start to effectively short with the last one ending so |
| 312 | // we don't miss any samples. It'd be great for the SAADC to offer a SHORTS | 300 | // we don't miss any samples. It'd be great for the SAADC to offer a SHORTS |
| 313 | // register instead, but it doesn't, so we must use PPI. | 301 | // register instead, but it doesn't, so we must use PPI. |
| 314 | let mut start_ppi = | 302 | let mut start_ppi = Ppi::new_one_to_one( |
| 315 | Ppi::new_one_to_one(ppi_ch1, Event::from_reg(&r.events_end), Task::from_reg(&r.tasks_start)); | 303 | ppi_ch1, |
| 304 | Event::from_reg(r.events_end()), | ||
| 305 | Task::from_reg(r.tasks_start()), | ||
| 306 | ); | ||
| 316 | start_ppi.enable(); | 307 | start_ppi.enable(); |
| 317 | 308 | ||
| 318 | let timer = Timer::new(timer); | 309 | let timer = Timer::new(timer); |
| @@ -322,7 +313,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 322 | 313 | ||
| 323 | let timer_cc = timer.cc(0); | 314 | let timer_cc = timer.cc(0); |
| 324 | 315 | ||
| 325 | let mut sample_ppi = Ppi::new_one_to_one(ppi_ch2, timer_cc.event_compare(), Task::from_reg(&r.tasks_sample)); | 316 | let mut sample_ppi = Ppi::new_one_to_one(ppi_ch2, timer_cc.event_compare(), Task::from_reg(r.tasks_sample())); |
| 326 | 317 | ||
| 327 | timer.start(); | 318 | timer.start(); |
| 328 | 319 | ||
| @@ -355,43 +346,37 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 355 | // Establish mode and sample rate | 346 | // Establish mode and sample rate |
| 356 | match sample_rate_divisor { | 347 | match sample_rate_divisor { |
| 357 | Some(sr) => { | 348 | Some(sr) => { |
| 358 | r.samplerate.write(|w| unsafe { | 349 | r.samplerate().write(|w| { |
| 359 | w.cc().bits(sr); | 350 | w.set_cc(sr); |
| 360 | w.mode().timers(); | 351 | w.set_mode(vals::SamplerateMode::TIMERS); |
| 361 | w | ||
| 362 | }); | 352 | }); |
| 363 | r.tasks_sample.write(|w| unsafe { w.bits(1) }); // Need to kick-start the internal timer | 353 | r.tasks_sample().write_value(1); // Need to kick-start the internal timer |
| 364 | } | 354 | } |
| 365 | None => r.samplerate.write(|w| unsafe { | 355 | None => r.samplerate().write(|w| { |
| 366 | w.cc().bits(0); | 356 | w.set_cc(0); |
| 367 | w.mode().task(); | 357 | w.set_mode(vals::SamplerateMode::TASK); |
| 368 | w | ||
| 369 | }), | 358 | }), |
| 370 | } | 359 | } |
| 371 | 360 | ||
| 372 | // Set up the initial DMA | 361 | // Set up the initial DMA |
| 373 | r.result | 362 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); |
| 374 | .ptr | 363 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N) as _)); |
| 375 | .write(|w| unsafe { w.ptr().bits(bufs[0].as_mut_ptr() as u32) }); | ||
| 376 | r.result.maxcnt.write(|w| unsafe { w.maxcnt().bits((N0 * N) as _) }); | ||
| 377 | 364 | ||
| 378 | // Reset and enable the events | 365 | // Reset and enable the events |
| 379 | r.events_end.reset(); | 366 | r.events_end().write_value(0); |
| 380 | r.events_started.reset(); | 367 | r.events_started().write_value(0); |
| 381 | r.intenset.write(|w| { | 368 | r.intenset().write(|w| { |
| 382 | w.end().set(); | 369 | w.set_end(true); |
| 383 | w.started().set(); | 370 | w.set_started(true); |
| 384 | w | ||
| 385 | }); | 371 | }); |
| 386 | 372 | ||
| 387 | // Don't reorder the ADC start event before the previous writes. Hopefully self | 373 | // Don't reorder the ADC start event before the previous writes. Hopefully self |
| 388 | // wouldn't happen anyway. | 374 | // wouldn't happen anyway. |
| 389 | compiler_fence(Ordering::SeqCst); | 375 | compiler_fence(Ordering::SeqCst); |
| 390 | 376 | ||
| 391 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 377 | r.tasks_start().write_value(1); |
| 392 | 378 | ||
| 393 | let mut inited = false; | 379 | let mut inited = false; |
| 394 | |||
| 395 | let mut current_buffer = 0; | 380 | let mut current_buffer = 0; |
| 396 | 381 | ||
| 397 | // Wait for events and complete when the sampler indicates it has had enough. | 382 | // Wait for events and complete when the sampler indicates it has had enough. |
| @@ -400,11 +385,11 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 400 | 385 | ||
| 401 | WAKER.register(cx.waker()); | 386 | WAKER.register(cx.waker()); |
| 402 | 387 | ||
| 403 | if r.events_end.read().bits() != 0 { | 388 | if r.events_end().read() != 0 { |
| 404 | compiler_fence(Ordering::SeqCst); | 389 | compiler_fence(Ordering::SeqCst); |
| 405 | 390 | ||
| 406 | r.events_end.reset(); | 391 | r.events_end().write_value(0); |
| 407 | r.intenset.write(|w| w.end().set()); | 392 | r.intenset().write(|w| w.set_end(true)); |
| 408 | 393 | ||
| 409 | match callback(&bufs[current_buffer]) { | 394 | match callback(&bufs[current_buffer]) { |
| 410 | CallbackResult::Continue => { | 395 | CallbackResult::Continue => { |
| @@ -417,9 +402,9 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 417 | } | 402 | } |
| 418 | } | 403 | } |
| 419 | 404 | ||
| 420 | if r.events_started.read().bits() != 0 { | 405 | if r.events_started().read() != 0 { |
| 421 | r.events_started.reset(); | 406 | r.events_started().write_value(0); |
| 422 | r.intenset.write(|w| w.started().set()); | 407 | r.intenset().write(|w| w.set_started(true)); |
| 423 | 408 | ||
| 424 | if !inited { | 409 | if !inited { |
| 425 | init(); | 410 | init(); |
| @@ -427,9 +412,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 427 | } | 412 | } |
| 428 | 413 | ||
| 429 | let next_buffer = 1 - current_buffer; | 414 | let next_buffer = 1 - current_buffer; |
| 430 | r.result | 415 | r.result().ptr().write_value(bufs[next_buffer].as_mut_ptr() as u32); |
| 431 | .ptr | ||
| 432 | .write(|w| unsafe { w.ptr().bits(bufs[next_buffer].as_mut_ptr() as u32) }); | ||
| 433 | } | 416 | } |
| 434 | 417 | ||
| 435 | Poll::Pending | 418 | Poll::Pending |
| @@ -447,11 +430,11 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 447 | 430 | ||
| 448 | compiler_fence(Ordering::SeqCst); | 431 | compiler_fence(Ordering::SeqCst); |
| 449 | 432 | ||
| 450 | r.events_stopped.reset(); | 433 | r.events_stopped().write_value(0); |
| 451 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 434 | r.tasks_stop().write_value(1); |
| 452 | 435 | ||
| 453 | while r.events_stopped.read().bits() == 0 {} | 436 | while r.events_stopped().read() == 0 {} |
| 454 | r.events_stopped.reset(); | 437 | r.events_stopped().write_value(0); |
| 455 | } | 438 | } |
| 456 | } | 439 | } |
| 457 | 440 | ||
| @@ -481,21 +464,21 @@ impl<'d> Saadc<'d, 1> { | |||
| 481 | impl<'d, const N: usize> Drop for Saadc<'d, N> { | 464 | impl<'d, const N: usize> Drop for Saadc<'d, N> { |
| 482 | fn drop(&mut self) { | 465 | fn drop(&mut self) { |
| 483 | let r = Self::regs(); | 466 | let r = Self::regs(); |
| 484 | r.enable.write(|w| w.enable().disabled()); | 467 | r.enable().write(|w| w.set_enable(false)); |
| 485 | } | 468 | } |
| 486 | } | 469 | } |
| 487 | 470 | ||
| 488 | impl From<Gain> for GAIN_A { | 471 | impl From<Gain> for vals::Gain { |
| 489 | fn from(gain: Gain) -> Self { | 472 | fn from(gain: Gain) -> Self { |
| 490 | match gain { | 473 | match gain { |
| 491 | Gain::GAIN1_6 => GAIN_A::GAIN1_6, | 474 | Gain::GAIN1_6 => vals::Gain::GAIN1_6, |
| 492 | Gain::GAIN1_5 => GAIN_A::GAIN1_5, | 475 | Gain::GAIN1_5 => vals::Gain::GAIN1_5, |
| 493 | Gain::GAIN1_4 => GAIN_A::GAIN1_4, | 476 | Gain::GAIN1_4 => vals::Gain::GAIN1_4, |
| 494 | Gain::GAIN1_3 => GAIN_A::GAIN1_3, | 477 | Gain::GAIN1_3 => vals::Gain::GAIN1_3, |
| 495 | Gain::GAIN1_2 => GAIN_A::GAIN1_2, | 478 | Gain::GAIN1_2 => vals::Gain::GAIN1_2, |
| 496 | Gain::GAIN1 => GAIN_A::GAIN1, | 479 | Gain::GAIN1 => vals::Gain::GAIN1, |
| 497 | Gain::GAIN2 => GAIN_A::GAIN2, | 480 | Gain::GAIN2 => vals::Gain::GAIN2, |
| 498 | Gain::GAIN4 => GAIN_A::GAIN4, | 481 | Gain::GAIN4 => vals::Gain::GAIN4, |
| 499 | } | 482 | } |
| 500 | } | 483 | } |
| 501 | } | 484 | } |
| @@ -522,11 +505,11 @@ pub enum Gain { | |||
| 522 | GAIN4 = 7, | 505 | GAIN4 = 7, |
| 523 | } | 506 | } |
| 524 | 507 | ||
| 525 | impl From<Reference> for REFSEL_A { | 508 | impl From<Reference> for vals::Refsel { |
| 526 | fn from(reference: Reference) -> Self { | 509 | fn from(reference: Reference) -> Self { |
| 527 | match reference { | 510 | match reference { |
| 528 | Reference::INTERNAL => REFSEL_A::INTERNAL, | 511 | Reference::INTERNAL => vals::Refsel::INTERNAL, |
| 529 | Reference::VDD1_4 => REFSEL_A::VDD1_4, | 512 | Reference::VDD1_4 => vals::Refsel::VDD1_4, |
| 530 | } | 513 | } |
| 531 | } | 514 | } |
| 532 | } | 515 | } |
| @@ -541,13 +524,13 @@ pub enum Reference { | |||
| 541 | VDD1_4 = 1, | 524 | VDD1_4 = 1, |
| 542 | } | 525 | } |
| 543 | 526 | ||
| 544 | impl From<Resistor> for RESP_A { | 527 | impl From<Resistor> for vals::Resp { |
| 545 | fn from(resistor: Resistor) -> Self { | 528 | fn from(resistor: Resistor) -> Self { |
| 546 | match resistor { | 529 | match resistor { |
| 547 | Resistor::BYPASS => RESP_A::BYPASS, | 530 | Resistor::BYPASS => vals::Resp::BYPASS, |
| 548 | Resistor::PULLDOWN => RESP_A::PULLDOWN, | 531 | Resistor::PULLDOWN => vals::Resp::PULLDOWN, |
| 549 | Resistor::PULLUP => RESP_A::PULLUP, | 532 | Resistor::PULLUP => vals::Resp::PULLUP, |
| 550 | Resistor::VDD1_2 => RESP_A::VDD1_2, | 533 | Resistor::VDD1_2 => vals::Resp::VDD1_2, |
| 551 | } | 534 | } |
| 552 | } | 535 | } |
| 553 | } | 536 | } |
| @@ -566,15 +549,15 @@ pub enum Resistor { | |||
| 566 | VDD1_2 = 3, | 549 | VDD1_2 = 3, |
| 567 | } | 550 | } |
| 568 | 551 | ||
| 569 | impl From<Time> for TACQ_A { | 552 | impl From<Time> for vals::Tacq { |
| 570 | fn from(time: Time) -> Self { | 553 | fn from(time: Time) -> Self { |
| 571 | match time { | 554 | match time { |
| 572 | Time::_3US => TACQ_A::_3US, | 555 | Time::_3US => vals::Tacq::_3US, |
| 573 | Time::_5US => TACQ_A::_5US, | 556 | Time::_5US => vals::Tacq::_5US, |
| 574 | Time::_10US => TACQ_A::_10US, | 557 | Time::_10US => vals::Tacq::_10US, |
| 575 | Time::_15US => TACQ_A::_15US, | 558 | Time::_15US => vals::Tacq::_15US, |
| 576 | Time::_20US => TACQ_A::_20US, | 559 | Time::_20US => vals::Tacq::_20US, |
| 577 | Time::_40US => TACQ_A::_40US, | 560 | Time::_40US => vals::Tacq::_40US, |
| 578 | } | 561 | } |
| 579 | } | 562 | } |
| 580 | } | 563 | } |
| @@ -597,18 +580,18 @@ pub enum Time { | |||
| 597 | _40US = 5, | 580 | _40US = 5, |
| 598 | } | 581 | } |
| 599 | 582 | ||
| 600 | impl From<Oversample> for OVERSAMPLE_A { | 583 | impl From<Oversample> for vals::Oversample { |
| 601 | fn from(oversample: Oversample) -> Self { | 584 | fn from(oversample: Oversample) -> Self { |
| 602 | match oversample { | 585 | match oversample { |
| 603 | Oversample::BYPASS => OVERSAMPLE_A::BYPASS, | 586 | Oversample::BYPASS => vals::Oversample::BYPASS, |
| 604 | Oversample::OVER2X => OVERSAMPLE_A::OVER2X, | 587 | Oversample::OVER2X => vals::Oversample::OVER2X, |
| 605 | Oversample::OVER4X => OVERSAMPLE_A::OVER4X, | 588 | Oversample::OVER4X => vals::Oversample::OVER4X, |
| 606 | Oversample::OVER8X => OVERSAMPLE_A::OVER8X, | 589 | Oversample::OVER8X => vals::Oversample::OVER8X, |
| 607 | Oversample::OVER16X => OVERSAMPLE_A::OVER16X, | 590 | Oversample::OVER16X => vals::Oversample::OVER16X, |
| 608 | Oversample::OVER32X => OVERSAMPLE_A::OVER32X, | 591 | Oversample::OVER32X => vals::Oversample::OVER32X, |
| 609 | Oversample::OVER64X => OVERSAMPLE_A::OVER64X, | 592 | Oversample::OVER64X => vals::Oversample::OVER64X, |
| 610 | Oversample::OVER128X => OVERSAMPLE_A::OVER128X, | 593 | Oversample::OVER128X => vals::Oversample::OVER128X, |
| 611 | Oversample::OVER256X => OVERSAMPLE_A::OVER256X, | 594 | Oversample::OVER256X => vals::Oversample::OVER256X, |
| 612 | } | 595 | } |
| 613 | } | 596 | } |
| 614 | } | 597 | } |
| @@ -637,13 +620,13 @@ pub enum Oversample { | |||
| 637 | OVER256X = 8, | 620 | OVER256X = 8, |
| 638 | } | 621 | } |
| 639 | 622 | ||
| 640 | impl From<Resolution> for VAL_A { | 623 | impl From<Resolution> for vals::Val { |
| 641 | fn from(resolution: Resolution) -> Self { | 624 | fn from(resolution: Resolution) -> Self { |
| 642 | match resolution { | 625 | match resolution { |
| 643 | Resolution::_8BIT => VAL_A::_8BIT, | 626 | Resolution::_8BIT => vals::Val::_8BIT, |
| 644 | Resolution::_10BIT => VAL_A::_10BIT, | 627 | Resolution::_10BIT => vals::Val::_10BIT, |
| 645 | Resolution::_12BIT => VAL_A::_12BIT, | 628 | Resolution::_12BIT => vals::Val::_12BIT, |
| 646 | Resolution::_14BIT => VAL_A::_14BIT, | 629 | Resolution::_14BIT => vals::Val::_14BIT, |
| 647 | } | 630 | } |
| 648 | } | 631 | } |
| 649 | } | 632 | } |
| @@ -726,7 +709,7 @@ impl_peripheral!(VddInput); | |||
| 726 | #[cfg(not(feature = "_nrf91"))] | 709 | #[cfg(not(feature = "_nrf91"))] |
| 727 | impl_saadc_input!(@local, VddInput, VDD); | 710 | impl_saadc_input!(@local, VddInput, VDD); |
| 728 | #[cfg(feature = "_nrf91")] | 711 | #[cfg(feature = "_nrf91")] |
| 729 | impl_saadc_input!(@local, VddInput, VDDGPIO); | 712 | impl_saadc_input!(@local, VddInput, VDD_GPIO); |
| 730 | 713 | ||
| 731 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 714 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 732 | /// VDDH / 5 voltage. | 715 | /// VDDH / 5 voltage. |
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 52660711a..ffaee2dc5 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -13,12 +13,13 @@ use embassy_embedded_hal::SetConfig; | |||
| 13 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 13 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 14 | use embassy_sync::waitqueue::AtomicWaker; | 14 | use embassy_sync::waitqueue::AtomicWaker; |
| 15 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 15 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 16 | pub use pac::spim0::config::ORDER_A as BitOrder; | 16 | pub use pac::spim::vals::{Frequency, Order as BitOrder}; |
| 17 | pub use pac::spim0::frequency::FREQUENCY_A as Frequency; | ||
| 18 | 17 | ||
| 19 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 20 | use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _}; | 19 | use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _}; |
| 21 | use crate::interrupt::typelevel::Interrupt; | 20 | use crate::interrupt::typelevel::Interrupt; |
| 21 | use crate::pac::gpio::vals as gpiovals; | ||
| 22 | use crate::pac::spim::vals; | ||
| 22 | use crate::util::slice_in_ram_or; | 23 | use crate::util::slice_in_ram_or; |
| 23 | use crate::{interrupt, pac, Peripheral}; | 24 | use crate::{interrupt, pac, Peripheral}; |
| 24 | 25 | ||
| @@ -33,6 +34,7 @@ pub enum Error { | |||
| 33 | 34 | ||
| 34 | /// SPIM configuration. | 35 | /// SPIM configuration. |
| 35 | #[non_exhaustive] | 36 | #[non_exhaustive] |
| 37 | #[derive(Clone)] | ||
| 36 | pub struct Config { | 38 | pub struct Config { |
| 37 | /// Frequency | 39 | /// Frequency |
| 38 | pub frequency: Frequency, | 40 | pub frequency: Frequency, |
| @@ -54,9 +56,6 @@ pub struct Config { | |||
| 54 | 56 | ||
| 55 | /// Drive strength for the MOSI line. | 57 | /// Drive strength for the MOSI line. |
| 56 | pub mosi_drive: OutputDrive, | 58 | pub mosi_drive: OutputDrive, |
| 57 | |||
| 58 | /// Drive strength for the MISO line. | ||
| 59 | pub miso_drive: OutputDrive, | ||
| 60 | } | 59 | } |
| 61 | 60 | ||
| 62 | impl Default for Config { | 61 | impl Default for Config { |
| @@ -68,7 +67,6 @@ impl Default for Config { | |||
| 68 | orc: 0x00, | 67 | orc: 0x00, |
| 69 | sck_drive: OutputDrive::HighDrive, | 68 | sck_drive: OutputDrive::HighDrive, |
| 70 | mosi_drive: OutputDrive::HighDrive, | 69 | mosi_drive: OutputDrive::HighDrive, |
| 71 | miso_drive: OutputDrive::HighDrive, | ||
| 72 | } | 70 | } |
| 73 | } | 71 | } |
| 74 | } | 72 | } |
| @@ -87,15 +85,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 87 | { | 85 | { |
| 88 | // Ideally we should call this only during the first chunk transfer, | 86 | // Ideally we should call this only during the first chunk transfer, |
| 89 | // but so far calling this every time doesn't seem to be causing any issues. | 87 | // but so far calling this every time doesn't seem to be causing any issues. |
| 90 | if r.events_started.read().bits() != 0 { | 88 | if r.events_started().read() != 0 { |
| 91 | s.waker.wake(); | 89 | s.waker.wake(); |
| 92 | r.intenclr.write(|w| w.started().clear()); | 90 | r.intenclr().write(|w| w.set_started(true)); |
| 93 | } | 91 | } |
| 94 | } | 92 | } |
| 95 | 93 | ||
| 96 | if r.events_end.read().bits() != 0 { | 94 | if r.events_end().read() != 0 { |
| 97 | s.waker.wake(); | 95 | s.waker.wake(); |
| 98 | r.intenclr.write(|w| w.end().clear()); | 96 | r.intenclr().write(|w| w.set_end(true)); |
| 99 | } | 97 | } |
| 100 | } | 98 | } |
| 101 | } | 99 | } |
| @@ -173,16 +171,19 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 173 | 171 | ||
| 174 | // Configure pins | 172 | // Configure pins |
| 175 | if let Some(sck) = &sck { | 173 | if let Some(sck) = &sck { |
| 176 | sck.conf() | 174 | sck.conf().write(|w| { |
| 177 | .write(|w| w.dir().output().drive().variant(convert_drive(config.sck_drive))); | 175 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 176 | w.set_drive(convert_drive(config.sck_drive)) | ||
| 177 | }); | ||
| 178 | } | 178 | } |
| 179 | if let Some(mosi) = &mosi { | 179 | if let Some(mosi) = &mosi { |
| 180 | mosi.conf() | 180 | mosi.conf().write(|w| { |
| 181 | .write(|w| w.dir().output().drive().variant(convert_drive(config.mosi_drive))); | 181 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 182 | w.set_drive(convert_drive(config.mosi_drive)) | ||
| 183 | }); | ||
| 182 | } | 184 | } |
| 183 | if let Some(miso) = &miso { | 185 | if let Some(miso) = &miso { |
| 184 | miso.conf() | 186 | miso.conf().write(|w| w.set_input(gpiovals::Input::CONNECT)); |
| 185 | .write(|w| w.input().connect().drive().variant(convert_drive(config.miso_drive))); | ||
| 186 | } | 187 | } |
| 187 | 188 | ||
| 188 | match config.mode.polarity { | 189 | match config.mode.polarity { |
| @@ -205,12 +206,12 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 205 | } | 206 | } |
| 206 | 207 | ||
| 207 | // Select pins. | 208 | // Select pins. |
| 208 | r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); | 209 | r.psel().sck().write_value(sck.psel_bits()); |
| 209 | r.psel.mosi.write(|w| unsafe { w.bits(mosi.psel_bits()) }); | 210 | r.psel().mosi().write_value(mosi.psel_bits()); |
| 210 | r.psel.miso.write(|w| unsafe { w.bits(miso.psel_bits()) }); | 211 | r.psel().miso().write_value(miso.psel_bits()); |
| 211 | 212 | ||
| 212 | // Enable SPIM instance. | 213 | // Enable SPIM instance. |
| 213 | r.enable.write(|w| w.enable().enabled()); | 214 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 214 | 215 | ||
| 215 | let mut spim = Self { _p: spim }; | 216 | let mut spim = Self { _p: spim }; |
| 216 | 217 | ||
| @@ -218,7 +219,7 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 218 | Self::set_config(&mut spim, &config).unwrap(); | 219 | Self::set_config(&mut spim, &config).unwrap(); |
| 219 | 220 | ||
| 220 | // Disable all events interrupts | 221 | // Disable all events interrupts |
| 221 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 222 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 222 | 223 | ||
| 223 | T::Interrupt::unpend(); | 224 | T::Interrupt::unpend(); |
| 224 | unsafe { T::Interrupt::enable() }; | 225 | unsafe { T::Interrupt::enable() }; |
| @@ -241,13 +242,13 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 241 | 242 | ||
| 242 | // Set up the DMA read. | 243 | // Set up the DMA read. |
| 243 | let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length); | 244 | let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length); |
| 244 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(rx_ptr) }); | 245 | r.rxd().ptr().write_value(rx_ptr); |
| 245 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) }); | 246 | r.rxd().maxcnt().write(|w| w.set_maxcnt(rx_len as _)); |
| 246 | 247 | ||
| 247 | // Set up the DMA write. | 248 | // Set up the DMA write. |
| 248 | let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length); | 249 | let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length); |
| 249 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(tx_ptr) }); | 250 | r.txd().ptr().write_value(tx_ptr); |
| 250 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) }); | 251 | r.txd().maxcnt().write(|w| w.set_maxcnt(tx_len as _)); |
| 251 | 252 | ||
| 252 | /* | 253 | /* |
| 253 | trace!("XFER: offset: {}, length: {}", offset, length); | 254 | trace!("XFER: offset: {}, length: {}", offset, length); |
| @@ -259,26 +260,26 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 259 | if offset == 0 { | 260 | if offset == 0 { |
| 260 | let s = T::state(); | 261 | let s = T::state(); |
| 261 | 262 | ||
| 262 | r.events_started.reset(); | 263 | r.events_started().write_value(0); |
| 263 | 264 | ||
| 264 | // Set rx/tx buffer lengths to 0... | 265 | // Set rx/tx buffer lengths to 0... |
| 265 | r.txd.maxcnt.reset(); | 266 | r.txd().maxcnt().write(|_| ()); |
| 266 | r.rxd.maxcnt.reset(); | 267 | r.rxd().maxcnt().write(|_| ()); |
| 267 | 268 | ||
| 268 | // ...and keep track of original buffer lengths... | 269 | // ...and keep track of original buffer lengths... |
| 269 | s.tx.store(tx_len as _, Ordering::Relaxed); | 270 | s.tx.store(tx_len as _, Ordering::Relaxed); |
| 270 | s.rx.store(rx_len as _, Ordering::Relaxed); | 271 | s.rx.store(rx_len as _, Ordering::Relaxed); |
| 271 | 272 | ||
| 272 | // ...signalling the start of the fake transfer. | 273 | // ...signalling the start of the fake transfer. |
| 273 | r.intenset.write(|w| w.started().bit(true)); | 274 | r.intenset().write(|w| w.set_started(true)); |
| 274 | } | 275 | } |
| 275 | 276 | ||
| 276 | // Reset and enable the event | 277 | // Reset and enable the event |
| 277 | r.events_end.reset(); | 278 | r.events_end().write_value(0); |
| 278 | r.intenset.write(|w| w.end().set()); | 279 | r.intenset().write(|w| w.set_end(true)); |
| 279 | 280 | ||
| 280 | // Start SPI transaction. | 281 | // Start SPI transaction. |
| 281 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 282 | r.tasks_start().write_value(1); |
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | fn blocking_inner_from_ram_chunk(&mut self, rx: *mut [u8], tx: *const [u8], offset: usize, length: usize) { | 285 | fn blocking_inner_from_ram_chunk(&mut self, rx: *mut [u8], tx: *const [u8], offset: usize, length: usize) { |
| @@ -290,7 +291,7 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 290 | } | 291 | } |
| 291 | 292 | ||
| 292 | // Wait for 'end' event. | 293 | // Wait for 'end' event. |
| 293 | while T::regs().events_end.read().bits() == 0 {} | 294 | while T::regs().events_end().read() == 0 {} |
| 294 | 295 | ||
| 295 | compiler_fence(Ordering::SeqCst); | 296 | compiler_fence(Ordering::SeqCst); |
| 296 | } | 297 | } |
| @@ -338,7 +339,7 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 338 | // Wait for 'end' event. | 339 | // Wait for 'end' event. |
| 339 | poll_fn(|cx| { | 340 | poll_fn(|cx| { |
| 340 | T::state().waker.register(cx.waker()); | 341 | T::state().waker.register(cx.waker()); |
| 341 | if T::regs().events_end.read().bits() != 0 { | 342 | if T::regs().events_end().read() != 0 { |
| 342 | return Poll::Ready(()); | 343 | return Poll::Ready(()); |
| 343 | } | 344 | } |
| 344 | 345 | ||
| @@ -442,24 +443,20 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 442 | #[cfg(feature = "_nrf52832_anomaly_109")] | 443 | #[cfg(feature = "_nrf52832_anomaly_109")] |
| 443 | fn nrf52832_dma_workaround_status(&mut self) -> Poll<()> { | 444 | fn nrf52832_dma_workaround_status(&mut self) -> Poll<()> { |
| 444 | let r = T::regs(); | 445 | let r = T::regs(); |
| 445 | if r.events_started.read().bits() != 0 { | 446 | if r.events_started().read() != 0 { |
| 446 | let s = T::state(); | 447 | let s = T::state(); |
| 447 | 448 | ||
| 448 | // Handle the first "fake" transmission | 449 | // Handle the first "fake" transmission |
| 449 | r.events_started.reset(); | 450 | r.events_started().write_value(0); |
| 450 | r.events_end.reset(); | 451 | r.events_end().write_value(0); |
| 451 | 452 | ||
| 452 | // Update DMA registers with correct rx/tx buffer sizes | 453 | // Update DMA registers with correct rx/tx buffer sizes |
| 453 | r.rxd | 454 | r.rxd().maxcnt().write(|w| w.set_maxcnt(s.rx.load(Ordering::Relaxed))); |
| 454 | .maxcnt | 455 | r.txd().maxcnt().write(|w| w.set_maxcnt(s.tx.load(Ordering::Relaxed))); |
| 455 | .write(|w| unsafe { w.maxcnt().bits(s.rx.load(Ordering::Relaxed)) }); | 456 | |
| 456 | r.txd | 457 | r.intenset().write(|w| w.set_end(true)); |
| 457 | .maxcnt | ||
| 458 | .write(|w| unsafe { w.maxcnt().bits(s.tx.load(Ordering::Relaxed)) }); | ||
| 459 | |||
| 460 | r.intenset.write(|w| w.end().set()); | ||
| 461 | // ... and start actual, hopefully glitch-free transmission | 458 | // ... and start actual, hopefully glitch-free transmission |
| 462 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 459 | r.tasks_start().write_value(1); |
| 463 | return Poll::Ready(()); | 460 | return Poll::Ready(()); |
| 464 | } | 461 | } |
| 465 | Poll::Pending | 462 | Poll::Pending |
| @@ -474,11 +471,11 @@ impl<'d, T: Instance> Drop for Spim<'d, T> { | |||
| 474 | 471 | ||
| 475 | // disable! | 472 | // disable! |
| 476 | let r = T::regs(); | 473 | let r = T::regs(); |
| 477 | r.enable.write(|w| w.enable().disabled()); | 474 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 478 | 475 | ||
| 479 | gpio::deconfigure_pin(r.psel.sck.read().bits()); | 476 | gpio::deconfigure_pin(r.psel().sck().read()); |
| 480 | gpio::deconfigure_pin(r.psel.miso.read().bits()); | 477 | gpio::deconfigure_pin(r.psel().miso().read()); |
| 481 | gpio::deconfigure_pin(r.psel.mosi.read().bits()); | 478 | gpio::deconfigure_pin(r.psel().mosi().read()); |
| 482 | 479 | ||
| 483 | // Disable all events interrupts | 480 | // Disable all events interrupts |
| 484 | T::Interrupt::disable(); | 481 | T::Interrupt::disable(); |
| @@ -508,7 +505,7 @@ impl State { | |||
| 508 | } | 505 | } |
| 509 | 506 | ||
| 510 | pub(crate) trait SealedInstance { | 507 | pub(crate) trait SealedInstance { |
| 511 | fn regs() -> &'static pac::spim0::RegisterBlock; | 508 | fn regs() -> pac::spim::Spim; |
| 512 | fn state() -> &'static State; | 509 | fn state() -> &'static State; |
| 513 | } | 510 | } |
| 514 | 511 | ||
| @@ -522,8 +519,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { | |||
| 522 | macro_rules! impl_spim { | 519 | macro_rules! impl_spim { |
| 523 | ($type:ident, $pac_type:ident, $irq:ident) => { | 520 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 524 | impl crate::spim::SealedInstance for peripherals::$type { | 521 | impl crate::spim::SealedInstance for peripherals::$type { |
| 525 | fn regs() -> &'static pac::spim0::RegisterBlock { | 522 | fn regs() -> pac::spim::Spim { |
| 526 | unsafe { &*pac::$pac_type::ptr() } | 523 | pac::$pac_type |
| 527 | } | 524 | } |
| 528 | fn state() -> &'static crate::spim::State { | 525 | fn state() -> &'static crate::spim::State { |
| 529 | static STATE: crate::spim::State = crate::spim::State::new(); | 526 | static STATE: crate::spim::State = crate::spim::State::new(); |
| @@ -621,40 +618,35 @@ impl<'d, T: Instance> SetConfig for Spim<'d, T> { | |||
| 621 | let r = T::regs(); | 618 | let r = T::regs(); |
| 622 | // Configure mode. | 619 | // Configure mode. |
| 623 | let mode = config.mode; | 620 | let mode = config.mode; |
| 624 | r.config.write(|w| { | 621 | r.config().write(|w| { |
| 622 | w.set_order(config.bit_order); | ||
| 625 | match mode { | 623 | match mode { |
| 626 | MODE_0 => { | 624 | MODE_0 => { |
| 627 | w.order().variant(config.bit_order); | 625 | w.set_cpol(vals::Cpol::ACTIVE_HIGH); |
| 628 | w.cpol().active_high(); | 626 | w.set_cpha(vals::Cpha::LEADING); |
| 629 | w.cpha().leading(); | ||
| 630 | } | 627 | } |
| 631 | MODE_1 => { | 628 | MODE_1 => { |
| 632 | w.order().variant(config.bit_order); | 629 | w.set_cpol(vals::Cpol::ACTIVE_HIGH); |
| 633 | w.cpol().active_high(); | 630 | w.set_cpha(vals::Cpha::TRAILING); |
| 634 | w.cpha().trailing(); | ||
| 635 | } | 631 | } |
| 636 | MODE_2 => { | 632 | MODE_2 => { |
| 637 | w.order().variant(config.bit_order); | 633 | w.set_cpol(vals::Cpol::ACTIVE_LOW); |
| 638 | w.cpol().active_low(); | 634 | w.set_cpha(vals::Cpha::LEADING); |
| 639 | w.cpha().leading(); | ||
| 640 | } | 635 | } |
| 641 | MODE_3 => { | 636 | MODE_3 => { |
| 642 | w.order().variant(config.bit_order); | 637 | w.set_cpol(vals::Cpol::ACTIVE_LOW); |
| 643 | w.cpol().active_low(); | 638 | w.set_cpha(vals::Cpha::TRAILING); |
| 644 | w.cpha().trailing(); | ||
| 645 | } | 639 | } |
| 646 | } | 640 | } |
| 647 | |||
| 648 | w | ||
| 649 | }); | 641 | }); |
| 650 | 642 | ||
| 651 | // Configure frequency. | 643 | // Configure frequency. |
| 652 | let frequency = config.frequency; | 644 | let frequency = config.frequency; |
| 653 | r.frequency.write(|w| w.frequency().variant(frequency)); | 645 | r.frequency().write(|w| w.set_frequency(frequency)); |
| 654 | 646 | ||
| 655 | // Set over-read character | 647 | // Set over-read character |
| 656 | let orc = config.orc; | 648 | let orc = config.orc; |
| 657 | r.orc.write(|w| unsafe { w.orc().bits(orc) }); | 649 | r.orc().write(|w| w.set_orc(orc)); |
| 658 | 650 | ||
| 659 | Ok(()) | 651 | Ok(()) |
| 660 | } | 652 | } |
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index e98b34369..a363e5909 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -10,11 +10,13 @@ use embassy_embedded_hal::SetConfig; | |||
| 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 10 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 12 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 13 | pub use pac::spis0::config::ORDER_A as BitOrder; | 13 | pub use pac::spis::vals::Order as BitOrder; |
| 14 | 14 | ||
| 15 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 15 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 16 | use crate::gpio::{self, AnyPin, Pin as GpioPin, SealedPin as _}; | 16 | use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, SealedPin as _}; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::gpio::vals as gpiovals; | ||
| 19 | use crate::pac::spis::vals; | ||
| 18 | use crate::util::slice_in_ram_or; | 20 | use crate::util::slice_in_ram_or; |
| 19 | use crate::{interrupt, pac, Peripheral}; | 21 | use crate::{interrupt, pac, Peripheral}; |
| 20 | 22 | ||
| @@ -54,6 +56,9 @@ pub struct Config { | |||
| 54 | 56 | ||
| 55 | /// Automatically make the firmware side acquire the semaphore on transfer end. | 57 | /// Automatically make the firmware side acquire the semaphore on transfer end. |
| 56 | pub auto_acquire: bool, | 58 | pub auto_acquire: bool, |
| 59 | |||
| 60 | /// Drive strength for the MISO line. | ||
| 61 | pub miso_drive: OutputDrive, | ||
| 57 | } | 62 | } |
| 58 | 63 | ||
| 59 | impl Default for Config { | 64 | impl Default for Config { |
| @@ -64,6 +69,7 @@ impl Default for Config { | |||
| 64 | orc: 0x00, | 69 | orc: 0x00, |
| 65 | def: 0x00, | 70 | def: 0x00, |
| 66 | auto_acquire: true, | 71 | auto_acquire: true, |
| 72 | miso_drive: OutputDrive::HighDrive, | ||
| 67 | } | 73 | } |
| 68 | } | 74 | } |
| 69 | } | 75 | } |
| @@ -78,14 +84,14 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 78 | let r = T::regs(); | 84 | let r = T::regs(); |
| 79 | let s = T::state(); | 85 | let s = T::state(); |
| 80 | 86 | ||
| 81 | if r.events_end.read().bits() != 0 { | 87 | if r.events_end().read() != 0 { |
| 82 | s.waker.wake(); | 88 | s.waker.wake(); |
| 83 | r.intenclr.write(|w| w.end().clear()); | 89 | r.intenclr().write(|w| w.set_end(true)); |
| 84 | } | 90 | } |
| 85 | 91 | ||
| 86 | if r.events_acquired.read().bits() != 0 { | 92 | if r.events_acquired().read() != 0 { |
| 87 | s.waker.wake(); | 93 | s.waker.wake(); |
| 88 | r.intenclr.write(|w| w.acquired().clear()); | 94 | r.intenclr().write(|w| w.set_acquired(true)); |
| 89 | } | 95 | } |
| 90 | } | 96 | } |
| 91 | } | 97 | } |
| @@ -184,23 +190,26 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 184 | let r = T::regs(); | 190 | let r = T::regs(); |
| 185 | 191 | ||
| 186 | // Configure pins. | 192 | // Configure pins. |
| 187 | cs.conf().write(|w| w.input().connect().drive().h0h1()); | 193 | cs.conf().write(|w| w.set_input(gpiovals::Input::CONNECT)); |
| 188 | r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); | 194 | r.psel().csn().write_value(cs.psel_bits()); |
| 189 | if let Some(sck) = &sck { | 195 | if let Some(sck) = &sck { |
| 190 | sck.conf().write(|w| w.input().connect().drive().h0h1()); | 196 | sck.conf().write(|w| w.set_input(gpiovals::Input::CONNECT)); |
| 191 | r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); | 197 | r.psel().sck().write_value(sck.psel_bits()); |
| 192 | } | 198 | } |
| 193 | if let Some(mosi) = &mosi { | 199 | if let Some(mosi) = &mosi { |
| 194 | mosi.conf().write(|w| w.input().connect().drive().h0h1()); | 200 | mosi.conf().write(|w| w.set_input(gpiovals::Input::CONNECT)); |
| 195 | r.psel.mosi.write(|w| unsafe { w.bits(mosi.psel_bits()) }); | 201 | r.psel().mosi().write_value(mosi.psel_bits()); |
| 196 | } | 202 | } |
| 197 | if let Some(miso) = &miso { | 203 | if let Some(miso) = &miso { |
| 198 | miso.conf().write(|w| w.dir().output().drive().h0h1()); | 204 | miso.conf().write(|w| { |
| 199 | r.psel.miso.write(|w| unsafe { w.bits(miso.psel_bits()) }); | 205 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 206 | w.set_drive(convert_drive(config.miso_drive)) | ||
| 207 | }); | ||
| 208 | r.psel().miso().write_value(miso.psel_bits()); | ||
| 200 | } | 209 | } |
| 201 | 210 | ||
| 202 | // Enable SPIS instance. | 211 | // Enable SPIS instance. |
| 203 | r.enable.write(|w| w.enable().enabled()); | 212 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 204 | 213 | ||
| 205 | let mut spis = Self { _p: spis }; | 214 | let mut spis = Self { _p: spis }; |
| 206 | 215 | ||
| @@ -208,7 +217,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 208 | Self::set_config(&mut spis, &config).unwrap(); | 217 | Self::set_config(&mut spis, &config).unwrap(); |
| 209 | 218 | ||
| 210 | // Disable all events interrupts. | 219 | // Disable all events interrupts. |
| 211 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 220 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 212 | 221 | ||
| 213 | T::Interrupt::unpend(); | 222 | T::Interrupt::unpend(); |
| 214 | unsafe { T::Interrupt::enable() }; | 223 | unsafe { T::Interrupt::enable() }; |
| @@ -229,21 +238,21 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 229 | if tx.len() > EASY_DMA_SIZE { | 238 | if tx.len() > EASY_DMA_SIZE { |
| 230 | return Err(Error::TxBufferTooLong); | 239 | return Err(Error::TxBufferTooLong); |
| 231 | } | 240 | } |
| 232 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(tx as *const u8 as _) }); | 241 | r.txd().ptr().write_value(tx as *const u8 as _); |
| 233 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx.len() as _) }); | 242 | r.txd().maxcnt().write(|w| w.set_maxcnt(tx.len() as _)); |
| 234 | 243 | ||
| 235 | // Set up the DMA read. | 244 | // Set up the DMA read. |
| 236 | if rx.len() > EASY_DMA_SIZE { | 245 | if rx.len() > EASY_DMA_SIZE { |
| 237 | return Err(Error::RxBufferTooLong); | 246 | return Err(Error::RxBufferTooLong); |
| 238 | } | 247 | } |
| 239 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(rx as *mut u8 as _) }); | 248 | r.rxd().ptr().write_value(rx as *mut u8 as _); |
| 240 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx.len() as _) }); | 249 | r.rxd().maxcnt().write(|w| w.set_maxcnt(rx.len() as _)); |
| 241 | 250 | ||
| 242 | // Reset end event. | 251 | // Reset end event. |
| 243 | r.events_end.reset(); | 252 | r.events_end().write_value(0); |
| 244 | 253 | ||
| 245 | // Release the semaphore. | 254 | // Release the semaphore. |
| 246 | r.tasks_release.write(|w| unsafe { w.bits(1) }); | 255 | r.tasks_release().write_value(1); |
| 247 | 256 | ||
| 248 | Ok(()) | 257 | Ok(()) |
| 249 | } | 258 | } |
| @@ -253,20 +262,20 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 253 | let r = T::regs(); | 262 | let r = T::regs(); |
| 254 | 263 | ||
| 255 | // Acquire semaphore. | 264 | // Acquire semaphore. |
| 256 | if r.semstat.read().bits() != 1 { | 265 | if r.semstat().read().0 != 1 { |
| 257 | r.events_acquired.reset(); | 266 | r.events_acquired().write_value(0); |
| 258 | r.tasks_acquire.write(|w| unsafe { w.bits(1) }); | 267 | r.tasks_acquire().write_value(1); |
| 259 | // Wait until CPU has acquired the semaphore. | 268 | // Wait until CPU has acquired the semaphore. |
| 260 | while r.semstat.read().bits() != 1 {} | 269 | while r.semstat().read().0 != 1 {} |
| 261 | } | 270 | } |
| 262 | 271 | ||
| 263 | self.prepare(rx, tx)?; | 272 | self.prepare(rx, tx)?; |
| 264 | 273 | ||
| 265 | // Wait for 'end' event. | 274 | // Wait for 'end' event. |
| 266 | while r.events_end.read().bits() == 0 {} | 275 | while r.events_end().read() == 0 {} |
| 267 | 276 | ||
| 268 | let n_rx = r.rxd.amount.read().bits() as usize; | 277 | let n_rx = r.rxd().amount().read().0 as usize; |
| 269 | let n_tx = r.txd.amount.read().bits() as usize; | 278 | let n_tx = r.txd().amount().read().0 as usize; |
| 270 | 279 | ||
| 271 | compiler_fence(Ordering::SeqCst); | 280 | compiler_fence(Ordering::SeqCst); |
| 272 | 281 | ||
| @@ -291,22 +300,25 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 291 | let s = T::state(); | 300 | let s = T::state(); |
| 292 | 301 | ||
| 293 | // Clear status register. | 302 | // Clear status register. |
| 294 | r.status.write(|w| w.overflow().clear().overread().clear()); | 303 | r.status().write(|w| { |
| 304 | w.set_overflow(true); | ||
| 305 | w.set_overread(true); | ||
| 306 | }); | ||
| 295 | 307 | ||
| 296 | // Acquire semaphore. | 308 | // Acquire semaphore. |
| 297 | if r.semstat.read().bits() != 1 { | 309 | if r.semstat().read().0 != 1 { |
| 298 | // Reset and enable the acquire event. | 310 | // Reset and enable the acquire event. |
| 299 | r.events_acquired.reset(); | 311 | r.events_acquired().write_value(0); |
| 300 | r.intenset.write(|w| w.acquired().set()); | 312 | r.intenset().write(|w| w.set_acquired(true)); |
| 301 | 313 | ||
| 302 | // Request acquiring the SPIS semaphore. | 314 | // Request acquiring the SPIS semaphore. |
| 303 | r.tasks_acquire.write(|w| unsafe { w.bits(1) }); | 315 | r.tasks_acquire().write_value(1); |
| 304 | 316 | ||
| 305 | // Wait until CPU has acquired the semaphore. | 317 | // Wait until CPU has acquired the semaphore. |
| 306 | poll_fn(|cx| { | 318 | poll_fn(|cx| { |
| 307 | s.waker.register(cx.waker()); | 319 | s.waker.register(cx.waker()); |
| 308 | if r.events_acquired.read().bits() == 1 { | 320 | if r.events_acquired().read() == 1 { |
| 309 | r.events_acquired.reset(); | 321 | r.events_acquired().write_value(0); |
| 310 | return Poll::Ready(()); | 322 | return Poll::Ready(()); |
| 311 | } | 323 | } |
| 312 | Poll::Pending | 324 | Poll::Pending |
| @@ -317,19 +329,19 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 317 | self.prepare(rx, tx)?; | 329 | self.prepare(rx, tx)?; |
| 318 | 330 | ||
| 319 | // Wait for 'end' event. | 331 | // Wait for 'end' event. |
| 320 | r.intenset.write(|w| w.end().set()); | 332 | r.intenset().write(|w| w.set_end(true)); |
| 321 | poll_fn(|cx| { | 333 | poll_fn(|cx| { |
| 322 | s.waker.register(cx.waker()); | 334 | s.waker.register(cx.waker()); |
| 323 | if r.events_end.read().bits() != 0 { | 335 | if r.events_end().read() != 0 { |
| 324 | r.events_end.reset(); | 336 | r.events_end().write_value(0); |
| 325 | return Poll::Ready(()); | 337 | return Poll::Ready(()); |
| 326 | } | 338 | } |
| 327 | Poll::Pending | 339 | Poll::Pending |
| 328 | }) | 340 | }) |
| 329 | .await; | 341 | .await; |
| 330 | 342 | ||
| 331 | let n_rx = r.rxd.amount.read().bits() as usize; | 343 | let n_rx = r.rxd().amount().read().0 as usize; |
| 332 | let n_tx = r.txd.amount.read().bits() as usize; | 344 | let n_tx = r.txd().amount().read().0 as usize; |
| 333 | 345 | ||
| 334 | compiler_fence(Ordering::SeqCst); | 346 | compiler_fence(Ordering::SeqCst); |
| 335 | 347 | ||
| @@ -428,12 +440,12 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 428 | 440 | ||
| 429 | /// Checks if last transaction overread. | 441 | /// Checks if last transaction overread. |
| 430 | pub fn is_overread(&mut self) -> bool { | 442 | pub fn is_overread(&mut self) -> bool { |
| 431 | T::regs().status.read().overread().is_present() | 443 | T::regs().status().read().overread() |
| 432 | } | 444 | } |
| 433 | 445 | ||
| 434 | /// Checks if last transaction overflowed. | 446 | /// Checks if last transaction overflowed. |
| 435 | pub fn is_overflow(&mut self) -> bool { | 447 | pub fn is_overflow(&mut self) -> bool { |
| 436 | T::regs().status.read().overflow().is_present() | 448 | T::regs().status().read().overflow() |
| 437 | } | 449 | } |
| 438 | } | 450 | } |
| 439 | 451 | ||
| @@ -443,12 +455,12 @@ impl<'d, T: Instance> Drop for Spis<'d, T> { | |||
| 443 | 455 | ||
| 444 | // Disable | 456 | // Disable |
| 445 | let r = T::regs(); | 457 | let r = T::regs(); |
| 446 | r.enable.write(|w| w.enable().disabled()); | 458 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 447 | 459 | ||
| 448 | gpio::deconfigure_pin(r.psel.sck.read().bits()); | 460 | gpio::deconfigure_pin(r.psel().sck().read()); |
| 449 | gpio::deconfigure_pin(r.psel.csn.read().bits()); | 461 | gpio::deconfigure_pin(r.psel().csn().read()); |
| 450 | gpio::deconfigure_pin(r.psel.miso.read().bits()); | 462 | gpio::deconfigure_pin(r.psel().miso().read()); |
| 451 | gpio::deconfigure_pin(r.psel.mosi.read().bits()); | 463 | gpio::deconfigure_pin(r.psel().mosi().read()); |
| 452 | 464 | ||
| 453 | trace!("spis drop: done"); | 465 | trace!("spis drop: done"); |
| 454 | } | 466 | } |
| @@ -467,7 +479,7 @@ impl State { | |||
| 467 | } | 479 | } |
| 468 | 480 | ||
| 469 | pub(crate) trait SealedInstance { | 481 | pub(crate) trait SealedInstance { |
| 470 | fn regs() -> &'static pac::spis0::RegisterBlock; | 482 | fn regs() -> pac::spis::Spis; |
| 471 | fn state() -> &'static State; | 483 | fn state() -> &'static State; |
| 472 | } | 484 | } |
| 473 | 485 | ||
| @@ -481,8 +493,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { | |||
| 481 | macro_rules! impl_spis { | 493 | macro_rules! impl_spis { |
| 482 | ($type:ident, $pac_type:ident, $irq:ident) => { | 494 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 483 | impl crate::spis::SealedInstance for peripherals::$type { | 495 | impl crate::spis::SealedInstance for peripherals::$type { |
| 484 | fn regs() -> &'static pac::spis0::RegisterBlock { | 496 | fn regs() -> pac::spis::Spis { |
| 485 | unsafe { &*pac::$pac_type::ptr() } | 497 | pac::$pac_type |
| 486 | } | 498 | } |
| 487 | fn state() -> &'static crate::spis::State { | 499 | fn state() -> &'static crate::spis::State { |
| 488 | static STATE: crate::spis::State = crate::spis::State::new(); | 500 | static STATE: crate::spis::State = crate::spis::State::new(); |
| @@ -504,44 +516,39 @@ impl<'d, T: Instance> SetConfig for Spis<'d, T> { | |||
| 504 | let r = T::regs(); | 516 | let r = T::regs(); |
| 505 | // Configure mode. | 517 | // Configure mode. |
| 506 | let mode = config.mode; | 518 | let mode = config.mode; |
| 507 | r.config.write(|w| { | 519 | r.config().write(|w| { |
| 520 | w.set_order(config.bit_order); | ||
| 508 | match mode { | 521 | match mode { |
| 509 | MODE_0 => { | 522 | MODE_0 => { |
| 510 | w.order().variant(config.bit_order); | 523 | w.set_cpol(vals::Cpol::ACTIVE_HIGH); |
| 511 | w.cpol().active_high(); | 524 | w.set_cpha(vals::Cpha::LEADING); |
| 512 | w.cpha().leading(); | ||
| 513 | } | 525 | } |
| 514 | MODE_1 => { | 526 | MODE_1 => { |
| 515 | w.order().variant(config.bit_order); | 527 | w.set_cpol(vals::Cpol::ACTIVE_HIGH); |
| 516 | w.cpol().active_high(); | 528 | w.set_cpha(vals::Cpha::TRAILING); |
| 517 | w.cpha().trailing(); | ||
| 518 | } | 529 | } |
| 519 | MODE_2 => { | 530 | MODE_2 => { |
| 520 | w.order().variant(config.bit_order); | 531 | w.set_cpol(vals::Cpol::ACTIVE_LOW); |
| 521 | w.cpol().active_low(); | 532 | w.set_cpha(vals::Cpha::LEADING); |
| 522 | w.cpha().leading(); | ||
| 523 | } | 533 | } |
| 524 | MODE_3 => { | 534 | MODE_3 => { |
| 525 | w.order().variant(config.bit_order); | 535 | w.set_cpol(vals::Cpol::ACTIVE_LOW); |
| 526 | w.cpol().active_low(); | 536 | w.set_cpha(vals::Cpha::TRAILING); |
| 527 | w.cpha().trailing(); | ||
| 528 | } | 537 | } |
| 529 | } | 538 | } |
| 530 | |||
| 531 | w | ||
| 532 | }); | 539 | }); |
| 533 | 540 | ||
| 534 | // Set over-read character. | 541 | // Set over-read character. |
| 535 | let orc = config.orc; | 542 | let orc = config.orc; |
| 536 | r.orc.write(|w| unsafe { w.orc().bits(orc) }); | 543 | r.orc().write(|w| w.set_orc(orc)); |
| 537 | 544 | ||
| 538 | // Set default character. | 545 | // Set default character. |
| 539 | let def = config.def; | 546 | let def = config.def; |
| 540 | r.def.write(|w| unsafe { w.def().bits(def) }); | 547 | r.def().write(|w| w.set_def(def)); |
| 541 | 548 | ||
| 542 | // Configure auto-acquire on 'transfer end' event. | 549 | // Configure auto-acquire on 'transfer end' event. |
| 543 | let auto_acquire = config.auto_acquire; | 550 | let auto_acquire = config.auto_acquire; |
| 544 | r.shorts.write(|w| w.end_acquire().bit(auto_acquire)); | 551 | r.shorts().write(|w| w.set_end_acquire(auto_acquire)); |
| 545 | 552 | ||
| 546 | Ok(()) | 553 | Ok(()) |
| 547 | } | 554 | } |
diff --git a/embassy-nrf/src/temp.rs b/embassy-nrf/src/temp.rs index ed4a47713..1488c5c24 100644 --- a/embassy-nrf/src/temp.rs +++ b/embassy-nrf/src/temp.rs | |||
| @@ -19,8 +19,8 @@ pub struct InterruptHandler { | |||
| 19 | 19 | ||
| 20 | impl interrupt::typelevel::Handler<interrupt::typelevel::TEMP> for InterruptHandler { | 20 | impl interrupt::typelevel::Handler<interrupt::typelevel::TEMP> for InterruptHandler { |
| 21 | unsafe fn on_interrupt() { | 21 | unsafe fn on_interrupt() { |
| 22 | let r = unsafe { &*pac::TEMP::PTR }; | 22 | let r = pac::TEMP; |
| 23 | r.intenclr.write(|w| w.datardy().clear()); | 23 | r.intenclr().write(|w| w.set_datardy(true)); |
| 24 | WAKER.wake(); | 24 | WAKER.wake(); |
| 25 | } | 25 | } |
| 26 | } | 26 | } |
| @@ -72,21 +72,21 @@ impl<'d> Temp<'d> { | |||
| 72 | // In case the future is dropped, stop the task and reset events. | 72 | // In case the future is dropped, stop the task and reset events. |
| 73 | let on_drop = OnDrop::new(|| { | 73 | let on_drop = OnDrop::new(|| { |
| 74 | let t = Self::regs(); | 74 | let t = Self::regs(); |
| 75 | t.tasks_stop.write(|w| unsafe { w.bits(1) }); | 75 | t.tasks_stop().write_value(1); |
| 76 | t.events_datardy.reset(); | 76 | t.events_datardy().write_value(0); |
| 77 | }); | 77 | }); |
| 78 | 78 | ||
| 79 | let t = Self::regs(); | 79 | let t = Self::regs(); |
| 80 | t.intenset.write(|w| w.datardy().set()); | 80 | t.intenset().write(|w| w.set_datardy(true)); |
| 81 | unsafe { t.tasks_start.write(|w| w.bits(1)) }; | 81 | t.tasks_start().write_value(1); |
| 82 | 82 | ||
| 83 | let value = poll_fn(|cx| { | 83 | let value = poll_fn(|cx| { |
| 84 | WAKER.register(cx.waker()); | 84 | WAKER.register(cx.waker()); |
| 85 | if t.events_datardy.read().bits() == 0 { | 85 | if t.events_datardy().read() == 0 { |
| 86 | Poll::Pending | 86 | Poll::Pending |
| 87 | } else { | 87 | } else { |
| 88 | t.events_datardy.reset(); | 88 | t.events_datardy().write_value(0); |
| 89 | let raw = t.temp.read().bits(); | 89 | let raw = t.temp().read(); |
| 90 | Poll::Ready(I30F2::from_bits(raw as i32)) | 90 | Poll::Ready(I30F2::from_bits(raw as i32)) |
| 91 | } | 91 | } |
| 92 | }) | 92 | }) |
| @@ -95,7 +95,7 @@ impl<'d> Temp<'d> { | |||
| 95 | value | 95 | value |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | fn regs() -> &'static pac::temp::RegisterBlock { | 98 | fn regs() -> pac::temp::Temp { |
| 99 | unsafe { &*pac::TEMP::ptr() } | 99 | pac::TEMP |
| 100 | } | 100 | } |
| 101 | } | 101 | } |
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 3407c9504..e39c4ed52 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs | |||
| @@ -10,8 +10,8 @@ use embassy_time_driver::{AlarmHandle, Driver}; | |||
| 10 | use crate::interrupt::InterruptExt; | 10 | use crate::interrupt::InterruptExt; |
| 11 | use crate::{interrupt, pac}; | 11 | use crate::{interrupt, pac}; |
| 12 | 12 | ||
| 13 | fn rtc() -> &'static pac::rtc0::RegisterBlock { | 13 | fn rtc() -> pac::rtc::Rtc { |
| 14 | unsafe { &*pac::RTC1::ptr() } | 14 | pac::RTC1 |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | /// Calculate the timestamp from the period count and the tick count. | 17 | /// Calculate the timestamp from the period count and the tick count. |
| @@ -128,19 +128,18 @@ embassy_time_driver::time_driver_impl!(static DRIVER: RtcDriver = RtcDriver { | |||
| 128 | impl RtcDriver { | 128 | impl RtcDriver { |
| 129 | fn init(&'static self, irq_prio: crate::interrupt::Priority) { | 129 | fn init(&'static self, irq_prio: crate::interrupt::Priority) { |
| 130 | let r = rtc(); | 130 | let r = rtc(); |
| 131 | r.cc[3].write(|w| unsafe { w.bits(0x800000) }); | 131 | r.cc(3).write(|w| w.set_compare(0x800000)); |
| 132 | 132 | ||
| 133 | r.intenset.write(|w| { | 133 | r.intenset().write(|w| { |
| 134 | let w = w.ovrflw().set(); | 134 | w.set_ovrflw(true); |
| 135 | let w = w.compare3().set(); | 135 | w.set_compare3(true); |
| 136 | w | ||
| 137 | }); | 136 | }); |
| 138 | 137 | ||
| 139 | r.tasks_clear.write(|w| unsafe { w.bits(1) }); | 138 | r.tasks_clear().write_value(1); |
| 140 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 139 | r.tasks_start().write_value(1); |
| 141 | 140 | ||
| 142 | // Wait for clear | 141 | // Wait for clear |
| 143 | while r.counter.read().bits() != 0 {} | 142 | while r.counter().read().0 != 0 {} |
| 144 | 143 | ||
| 145 | interrupt::RTC1.set_priority(irq_prio); | 144 | interrupt::RTC1.set_priority(irq_prio); |
| 146 | unsafe { interrupt::RTC1.enable() }; | 145 | unsafe { interrupt::RTC1.enable() }; |
| @@ -148,19 +147,19 @@ impl RtcDriver { | |||
| 148 | 147 | ||
| 149 | fn on_interrupt(&self) { | 148 | fn on_interrupt(&self) { |
| 150 | let r = rtc(); | 149 | let r = rtc(); |
| 151 | if r.events_ovrflw.read().bits() == 1 { | 150 | if r.events_ovrflw().read() == 1 { |
| 152 | r.events_ovrflw.write(|w| w); | 151 | r.events_ovrflw().write_value(0); |
| 153 | self.next_period(); | 152 | self.next_period(); |
| 154 | } | 153 | } |
| 155 | 154 | ||
| 156 | if r.events_compare[3].read().bits() == 1 { | 155 | if r.events_compare(3).read() == 1 { |
| 157 | r.events_compare[3].write(|w| w); | 156 | r.events_compare(3).write_value(0); |
| 158 | self.next_period(); | 157 | self.next_period(); |
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | for n in 0..ALARM_COUNT { | 160 | for n in 0..ALARM_COUNT { |
| 162 | if r.events_compare[n].read().bits() == 1 { | 161 | if r.events_compare(n).read() == 1 { |
| 163 | r.events_compare[n].write(|w| w); | 162 | r.events_compare(n).write_value(0); |
| 164 | critical_section::with(|cs| { | 163 | critical_section::with(|cs| { |
| 165 | self.trigger_alarm(n, cs); | 164 | self.trigger_alarm(n, cs); |
| 166 | }) | 165 | }) |
| @@ -181,7 +180,7 @@ impl RtcDriver { | |||
| 181 | 180 | ||
| 182 | if at < t + 0xc00000 { | 181 | if at < t + 0xc00000 { |
| 183 | // just enable it. `set_alarm` has already set the correct CC val. | 182 | // just enable it. `set_alarm` has already set the correct CC val. |
| 184 | r.intenset.write(|w| unsafe { w.bits(compare_n(n)) }); | 183 | r.intenset().write(|w| w.0 = compare_n(n)); |
| 185 | } | 184 | } |
| 186 | } | 185 | } |
| 187 | }) | 186 | }) |
| @@ -195,7 +194,7 @@ impl RtcDriver { | |||
| 195 | 194 | ||
| 196 | fn trigger_alarm(&self, n: usize, cs: CriticalSection) { | 195 | fn trigger_alarm(&self, n: usize, cs: CriticalSection) { |
| 197 | let r = rtc(); | 196 | let r = rtc(); |
| 198 | r.intenclr.write(|w| unsafe { w.bits(compare_n(n)) }); | 197 | r.intenclr().write(|w| w.0 = compare_n(n)); |
| 199 | 198 | ||
| 200 | let alarm = &self.alarms.borrow(cs)[n]; | 199 | let alarm = &self.alarms.borrow(cs)[n]; |
| 201 | alarm.timestamp.set(u64::MAX); | 200 | alarm.timestamp.set(u64::MAX); |
| @@ -215,7 +214,7 @@ impl Driver for RtcDriver { | |||
| 215 | // `period` MUST be read before `counter`, see comment at the top for details. | 214 | // `period` MUST be read before `counter`, see comment at the top for details. |
| 216 | let period = self.period.load(Ordering::Relaxed); | 215 | let period = self.period.load(Ordering::Relaxed); |
| 217 | compiler_fence(Ordering::Acquire); | 216 | compiler_fence(Ordering::Acquire); |
| 218 | let counter = rtc().counter.read().bits(); | 217 | let counter = rtc().counter().read().0; |
| 219 | calc_now(period, counter) | 218 | calc_now(period, counter) |
| 220 | } | 219 | } |
| 221 | 220 | ||
| @@ -252,7 +251,7 @@ impl Driver for RtcDriver { | |||
| 252 | if timestamp <= t { | 251 | if timestamp <= t { |
| 253 | // If alarm timestamp has passed the alarm will not fire. | 252 | // If alarm timestamp has passed the alarm will not fire. |
| 254 | // Disarm the alarm and return `false` to indicate that. | 253 | // Disarm the alarm and return `false` to indicate that. |
| 255 | r.intenclr.write(|w| unsafe { w.bits(compare_n(n)) }); | 254 | r.intenclr().write(|w| w.0 = compare_n(n)); |
| 256 | 255 | ||
| 257 | alarm.timestamp.set(u64::MAX); | 256 | alarm.timestamp.set(u64::MAX); |
| 258 | 257 | ||
| @@ -277,15 +276,15 @@ impl Driver for RtcDriver { | |||
| 277 | // by the Alarm trait contract. What's not allowed is triggering alarms *before* their scheduled time, | 276 | // by the Alarm trait contract. What's not allowed is triggering alarms *before* their scheduled time, |
| 278 | // and we don't do that here. | 277 | // and we don't do that here. |
| 279 | let safe_timestamp = timestamp.max(t + 3); | 278 | let safe_timestamp = timestamp.max(t + 3); |
| 280 | r.cc[n].write(|w| unsafe { w.bits(safe_timestamp as u32 & 0xFFFFFF) }); | 279 | r.cc(n).write(|w| w.set_compare(safe_timestamp as u32 & 0xFFFFFF)); |
| 281 | 280 | ||
| 282 | let diff = timestamp - t; | 281 | let diff = timestamp - t; |
| 283 | if diff < 0xc00000 { | 282 | if diff < 0xc00000 { |
| 284 | r.intenset.write(|w| unsafe { w.bits(compare_n(n)) }); | 283 | r.intenset().write(|w| w.0 = compare_n(n)); |
| 285 | } else { | 284 | } else { |
| 286 | // If it's too far in the future, don't setup the compare channel yet. | 285 | // If it's too far in the future, don't setup the compare channel yet. |
| 287 | // It will be setup later by `next_period`. | 286 | // It will be setup later by `next_period`. |
| 288 | r.intenclr.write(|w| unsafe { w.bits(compare_n(n)) }); | 287 | r.intenclr().write(|w| w.0 = compare_n(n)); |
| 289 | } | 288 | } |
| 290 | 289 | ||
| 291 | true | 290 | true |
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index ac5328ded..a9aeb40fa 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -8,13 +8,14 @@ | |||
| 8 | 8 | ||
| 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | 10 | ||
| 11 | use crate::pac::timer::vals; | ||
| 11 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| 12 | use crate::{pac, Peripheral}; | 13 | use crate::{pac, Peripheral}; |
| 13 | 14 | ||
| 14 | pub(crate) trait SealedInstance { | 15 | pub(crate) trait SealedInstance { |
| 15 | /// The number of CC registers this instance has. | 16 | /// The number of CC registers this instance has. |
| 16 | const CCS: usize; | 17 | const CCS: usize; |
| 17 | fn regs() -> &'static pac::timer0::RegisterBlock; | 18 | fn regs() -> pac::timer::Timer; |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | /// Basic Timer instance. | 21 | /// Basic Timer instance. |
| @@ -31,8 +32,8 @@ macro_rules! impl_timer { | |||
| 31 | ($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => { | 32 | ($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => { |
| 32 | impl crate::timer::SealedInstance for peripherals::$type { | 33 | impl crate::timer::SealedInstance for peripherals::$type { |
| 33 | const CCS: usize = $ccs; | 34 | const CCS: usize = $ccs; |
| 34 | fn regs() -> &'static pac::timer0::RegisterBlock { | 35 | fn regs() -> pac::timer::Timer { |
| 35 | unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) } | 36 | unsafe { pac::timer::Timer::from_ptr(pac::$pac_type.as_ptr()) } |
| 36 | } | 37 | } |
| 37 | } | 38 | } |
| 38 | impl crate::timer::Instance for peripherals::$type { | 39 | impl crate::timer::Instance for peripherals::$type { |
| @@ -114,19 +115,19 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 114 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. | 115 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. |
| 115 | this.stop(); | 116 | this.stop(); |
| 116 | 117 | ||
| 117 | #[cfg(not(feature = "nrf51"))] | 118 | regs.mode().write(|w| { |
| 118 | if _is_counter { | 119 | w.set_mode(match _is_counter { |
| 119 | regs.mode.write(|w| w.mode().low_power_counter()); | 120 | #[cfg(not(feature = "_nrf51"))] |
| 120 | } else { | 121 | true => vals::Mode::LOW_POWER_COUNTER, |
| 121 | regs.mode.write(|w| w.mode().timer()); | 122 | #[cfg(feature = "_nrf51")] |
| 122 | } | 123 | true => vals::Mode::COUNTER, |
| 123 | 124 | false => vals::Mode::TIMER, | |
| 124 | #[cfg(feature = "nrf51")] | 125 | }) |
| 125 | regs.mode.write(|w| w.mode().timer()); | 126 | }); |
| 126 | 127 | ||
| 127 | // Make the counter's max value as high as possible. | 128 | // Make the counter's max value as high as possible. |
| 128 | // TODO: is there a reason someone would want to set this lower? | 129 | // TODO: is there a reason someone would want to set this lower? |
| 129 | regs.bitmode.write(|w| w.bitmode()._32bit()); | 130 | regs.bitmode().write(|w| w.set_bitmode(vals::Bitmode::_32BIT)); |
| 130 | 131 | ||
| 131 | // Initialize the counter at 0. | 132 | // Initialize the counter at 0. |
| 132 | this.clear(); | 133 | this.clear(); |
| @@ -148,38 +149,38 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 148 | 149 | ||
| 149 | /// Starts the timer. | 150 | /// Starts the timer. |
| 150 | pub fn start(&self) { | 151 | pub fn start(&self) { |
| 151 | T::regs().tasks_start.write(|w| unsafe { w.bits(1) }) | 152 | T::regs().tasks_start().write_value(1) |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | /// Stops the timer. | 155 | /// Stops the timer. |
| 155 | pub fn stop(&self) { | 156 | pub fn stop(&self) { |
| 156 | T::regs().tasks_stop.write(|w| unsafe { w.bits(1) }) | 157 | T::regs().tasks_stop().write_value(1) |
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | /// Reset the timer's counter to 0. | 160 | /// Reset the timer's counter to 0. |
| 160 | pub fn clear(&self) { | 161 | pub fn clear(&self) { |
| 161 | T::regs().tasks_clear.write(|w| unsafe { w.bits(1) }) | 162 | T::regs().tasks_clear().write_value(1) |
| 162 | } | 163 | } |
| 163 | 164 | ||
| 164 | /// Returns the START task, for use with PPI. | 165 | /// Returns the START task, for use with PPI. |
| 165 | /// | 166 | /// |
| 166 | /// When triggered, this task starts the timer. | 167 | /// When triggered, this task starts the timer. |
| 167 | pub fn task_start(&self) -> Task<'d> { | 168 | pub fn task_start(&self) -> Task<'d> { |
| 168 | Task::from_reg(&T::regs().tasks_start) | 169 | Task::from_reg(T::regs().tasks_start()) |
| 169 | } | 170 | } |
| 170 | 171 | ||
| 171 | /// Returns the STOP task, for use with PPI. | 172 | /// Returns the STOP task, for use with PPI. |
| 172 | /// | 173 | /// |
| 173 | /// When triggered, this task stops the timer. | 174 | /// When triggered, this task stops the timer. |
| 174 | pub fn task_stop(&self) -> Task<'d> { | 175 | pub fn task_stop(&self) -> Task<'d> { |
| 175 | Task::from_reg(&T::regs().tasks_stop) | 176 | Task::from_reg(T::regs().tasks_stop()) |
| 176 | } | 177 | } |
| 177 | 178 | ||
| 178 | /// Returns the CLEAR task, for use with PPI. | 179 | /// Returns the CLEAR task, for use with PPI. |
| 179 | /// | 180 | /// |
| 180 | /// When triggered, this task resets the timer's counter to 0. | 181 | /// When triggered, this task resets the timer's counter to 0. |
| 181 | pub fn task_clear(&self) -> Task<'d> { | 182 | pub fn task_clear(&self) -> Task<'d> { |
| 182 | Task::from_reg(&T::regs().tasks_clear) | 183 | Task::from_reg(T::regs().tasks_clear()) |
| 183 | } | 184 | } |
| 184 | 185 | ||
| 185 | /// Returns the COUNT task, for use with PPI. | 186 | /// Returns the COUNT task, for use with PPI. |
| @@ -187,7 +188,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 187 | /// When triggered, this task increments the timer's counter by 1. | 188 | /// When triggered, this task increments the timer's counter by 1. |
| 188 | /// Only works in counter mode. | 189 | /// Only works in counter mode. |
| 189 | pub fn task_count(&self) -> Task<'d> { | 190 | pub fn task_count(&self) -> Task<'d> { |
| 190 | Task::from_reg(&T::regs().tasks_count) | 191 | Task::from_reg(T::regs().tasks_count()) |
| 191 | } | 192 | } |
| 192 | 193 | ||
| 193 | /// Change the timer's frequency. | 194 | /// Change the timer's frequency. |
| @@ -198,10 +199,10 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 198 | self.stop(); | 199 | self.stop(); |
| 199 | 200 | ||
| 200 | T::regs() | 201 | T::regs() |
| 201 | .prescaler | 202 | .prescaler() |
| 202 | // SAFETY: `frequency` is a variant of `Frequency`, | 203 | // SAFETY: `frequency` is a variant of `Frequency`, |
| 203 | // whose values are all in the range of 0-9 (the valid range of `prescaler`). | 204 | // whose values are all in the range of 0-9 (the valid range of `prescaler`). |
| 204 | .write(|w| unsafe { w.prescaler().bits(frequency as u8) }) | 205 | .write(|w| w.set_prescaler(frequency as u8)) |
| 205 | } | 206 | } |
| 206 | 207 | ||
| 207 | /// Returns this timer's `n`th CC register. | 208 | /// Returns this timer's `n`th CC register. |
| @@ -234,28 +235,19 @@ pub struct Cc<'d, T: Instance> { | |||
| 234 | impl<'d, T: Instance> Cc<'d, T> { | 235 | impl<'d, T: Instance> Cc<'d, T> { |
| 235 | /// Get the current value stored in the register. | 236 | /// Get the current value stored in the register. |
| 236 | pub fn read(&self) -> u32 { | 237 | pub fn read(&self) -> u32 { |
| 237 | #[cfg(not(feature = "nrf51"))] | 238 | return T::regs().cc(self.n).read(); |
| 238 | return T::regs().cc[self.n].read().cc().bits(); | ||
| 239 | |||
| 240 | #[cfg(feature = "nrf51")] | ||
| 241 | return T::regs().cc[self.n].read().bits(); | ||
| 242 | } | 239 | } |
| 243 | 240 | ||
| 244 | /// Set the value stored in the register. | 241 | /// Set the value stored in the register. |
| 245 | /// | 242 | /// |
| 246 | /// `event_compare` will fire when the timer's counter reaches this value. | 243 | /// `event_compare` will fire when the timer's counter reaches this value. |
| 247 | pub fn write(&self, value: u32) { | 244 | pub fn write(&self, value: u32) { |
| 248 | // SAFETY: there are no invalid values for the CC register. | 245 | T::regs().cc(self.n).write_value(value); |
| 249 | #[cfg(not(feature = "nrf51"))] | ||
| 250 | T::regs().cc[self.n].write(|w| unsafe { w.cc().bits(value) }); | ||
| 251 | |||
| 252 | #[cfg(feature = "nrf51")] | ||
| 253 | T::regs().cc[self.n].write(|w| unsafe { w.bits(value) }); | ||
| 254 | } | 246 | } |
| 255 | 247 | ||
| 256 | /// Capture the current value of the timer's counter in this register, and return it. | 248 | /// Capture the current value of the timer's counter in this register, and return it. |
| 257 | pub fn capture(&self) -> u32 { | 249 | pub fn capture(&self) -> u32 { |
| 258 | T::regs().tasks_capture[self.n].write(|w| unsafe { w.bits(1) }); | 250 | T::regs().tasks_capture(self.n).write_value(1); |
| 259 | self.read() | 251 | self.read() |
| 260 | } | 252 | } |
| 261 | 253 | ||
| @@ -263,14 +255,14 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 263 | /// | 255 | /// |
| 264 | /// When triggered, this task will capture the current value of the timer's counter in this register. | 256 | /// When triggered, this task will capture the current value of the timer's counter in this register. |
| 265 | pub fn task_capture(&self) -> Task<'d> { | 257 | pub fn task_capture(&self) -> Task<'d> { |
| 266 | Task::from_reg(&T::regs().tasks_capture) | 258 | Task::from_reg(T::regs().tasks_capture(self.n)) |
| 267 | } | 259 | } |
| 268 | 260 | ||
| 269 | /// Returns this CC register's COMPARE event, for use with PPI. | 261 | /// Returns this CC register's COMPARE event, for use with PPI. |
| 270 | /// | 262 | /// |
| 271 | /// This event will fire when the timer's counter reaches the value in this CC register. | 263 | /// This event will fire when the timer's counter reaches the value in this CC register. |
| 272 | pub fn event_compare(&self) -> Event<'d> { | 264 | pub fn event_compare(&self) -> Event<'d> { |
| 273 | Event::from_reg(&T::regs().events_compare[self.n]) | 265 | Event::from_reg(T::regs().events_compare(self.n)) |
| 274 | } | 266 | } |
| 275 | 267 | ||
| 276 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 268 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
| @@ -279,16 +271,12 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 279 | /// | 271 | /// |
| 280 | /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. | 272 | /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. |
| 281 | pub fn short_compare_clear(&self) { | 273 | pub fn short_compare_clear(&self) { |
| 282 | T::regs() | 274 | T::regs().shorts().modify(|w| w.set_compare_clear(self.n, true)) |
| 283 | .shorts | ||
| 284 | .modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.n)) }) | ||
| 285 | } | 275 | } |
| 286 | 276 | ||
| 287 | /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 277 | /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
| 288 | pub fn unshort_compare_clear(&self) { | 278 | pub fn unshort_compare_clear(&self) { |
| 289 | T::regs() | 279 | T::regs().shorts().modify(|w| w.set_compare_clear(self.n, false)) |
| 290 | .shorts | ||
| 291 | .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.n)) }) | ||
| 292 | } | 280 | } |
| 293 | 281 | ||
| 294 | /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. | 282 | /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. |
| @@ -297,15 +285,11 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 297 | /// | 285 | /// |
| 298 | /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. | 286 | /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. |
| 299 | pub fn short_compare_stop(&self) { | 287 | pub fn short_compare_stop(&self) { |
| 300 | T::regs() | 288 | T::regs().shorts().modify(|w| w.set_compare_stop(self.n, true)) |
| 301 | .shorts | ||
| 302 | .modify(|r, w| unsafe { w.bits(r.bits() | (1 << (8 + self.n))) }) | ||
| 303 | } | 289 | } |
| 304 | 290 | ||
| 305 | /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. | 291 | /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. |
| 306 | pub fn unshort_compare_stop(&self) { | 292 | pub fn unshort_compare_stop(&self) { |
| 307 | T::regs() | 293 | T::regs().shorts().modify(|w| w.set_compare_stop(self.n, false)) |
| 308 | .shorts | ||
| 309 | .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << (8 + self.n))) }) | ||
| 310 | } | 294 | } |
| 311 | } | 295 | } |
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 187fce021..ebad39df2 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -15,24 +15,16 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 15 | #[cfg(feature = "time")] | 15 | #[cfg(feature = "time")] |
| 16 | use embassy_time::{Duration, Instant}; | 16 | use embassy_time::{Duration, Instant}; |
| 17 | use embedded_hal_1::i2c::Operation; | 17 | use embedded_hal_1::i2c::Operation; |
| 18 | pub use pac::twim::vals::Frequency; | ||
| 18 | 19 | ||
| 19 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 20 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 20 | use crate::gpio::Pin as GpioPin; | 21 | use crate::gpio::Pin as GpioPin; |
| 21 | use crate::interrupt::typelevel::Interrupt; | 22 | use crate::interrupt::typelevel::Interrupt; |
| 23 | use crate::pac::gpio::vals as gpiovals; | ||
| 24 | use crate::pac::twim::vals; | ||
| 22 | use crate::util::slice_in_ram; | 25 | use crate::util::slice_in_ram; |
| 23 | use crate::{gpio, interrupt, pac, Peripheral}; | 26 | use crate::{gpio, interrupt, pac, Peripheral}; |
| 24 | 27 | ||
| 25 | /// TWI frequency | ||
| 26 | #[derive(Clone, Copy)] | ||
| 27 | pub enum Frequency { | ||
| 28 | /// 100 kbps | ||
| 29 | K100 = 26738688, | ||
| 30 | /// 250 kbps | ||
| 31 | K250 = 67108864, | ||
| 32 | /// 400 kbps | ||
| 33 | K400 = 104857600, | ||
| 34 | } | ||
| 35 | |||
| 36 | /// TWIM config. | 28 | /// TWIM config. |
| 37 | #[non_exhaustive] | 29 | #[non_exhaustive] |
| 38 | pub struct Config { | 30 | pub struct Config { |
| @@ -105,17 +97,17 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 105 | let r = T::regs(); | 97 | let r = T::regs(); |
| 106 | let s = T::state(); | 98 | let s = T::state(); |
| 107 | 99 | ||
| 108 | if r.events_suspended.read().bits() != 0 { | 100 | if r.events_suspended().read() != 0 { |
| 109 | s.end_waker.wake(); | 101 | s.end_waker.wake(); |
| 110 | r.intenclr.write(|w| w.suspended().clear()); | 102 | r.intenclr().write(|w| w.set_suspended(true)); |
| 111 | } | 103 | } |
| 112 | if r.events_stopped.read().bits() != 0 { | 104 | if r.events_stopped().read() != 0 { |
| 113 | s.end_waker.wake(); | 105 | s.end_waker.wake(); |
| 114 | r.intenclr.write(|w| w.stopped().clear()); | 106 | r.intenclr().write(|w| w.set_stopped(true)); |
| 115 | } | 107 | } |
| 116 | if r.events_error.read().bits() != 0 { | 108 | if r.events_error().read() != 0 { |
| 117 | s.end_waker.wake(); | 109 | s.end_waker.wake(); |
| 118 | r.intenclr.write(|w| w.error().clear()); | 110 | r.intenclr().write(|w| w.set_error(true)); |
| 119 | } | 111 | } |
| 120 | } | 112 | } |
| 121 | } | 113 | } |
| @@ -140,38 +132,34 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 140 | 132 | ||
| 141 | // Configure pins | 133 | // Configure pins |
| 142 | sda.conf().write(|w| { | 134 | sda.conf().write(|w| { |
| 143 | w.dir().input(); | 135 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 144 | w.input().connect(); | 136 | w.set_input(gpiovals::Input::CONNECT); |
| 145 | if config.sda_high_drive { | 137 | w.set_drive(match config.sda_high_drive { |
| 146 | w.drive().h0d1(); | 138 | true => gpiovals::Drive::H0D1, |
| 147 | } else { | 139 | false => gpiovals::Drive::S0D1, |
| 148 | w.drive().s0d1(); | 140 | }); |
| 149 | } | ||
| 150 | if config.sda_pullup { | 141 | if config.sda_pullup { |
| 151 | w.pull().pullup(); | 142 | w.set_pull(gpiovals::Pull::PULLUP); |
| 152 | } | 143 | } |
| 153 | w | ||
| 154 | }); | 144 | }); |
| 155 | scl.conf().write(|w| { | 145 | scl.conf().write(|w| { |
| 156 | w.dir().input(); | 146 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 157 | w.input().connect(); | 147 | w.set_input(gpiovals::Input::CONNECT); |
| 158 | if config.scl_high_drive { | 148 | w.set_drive(match config.scl_high_drive { |
| 159 | w.drive().h0d1(); | 149 | true => gpiovals::Drive::H0D1, |
| 160 | } else { | 150 | false => gpiovals::Drive::S0D1, |
| 161 | w.drive().s0d1(); | 151 | }); |
| 162 | } | 152 | if config.sda_pullup { |
| 163 | if config.scl_pullup { | 153 | w.set_pull(gpiovals::Pull::PULLUP); |
| 164 | w.pull().pullup(); | ||
| 165 | } | 154 | } |
| 166 | w | ||
| 167 | }); | 155 | }); |
| 168 | 156 | ||
| 169 | // Select pins. | 157 | // Select pins. |
| 170 | r.psel.sda.write(|w| unsafe { w.bits(sda.psel_bits()) }); | 158 | r.psel().sda().write_value(sda.psel_bits()); |
| 171 | r.psel.scl.write(|w| unsafe { w.bits(scl.psel_bits()) }); | 159 | r.psel().scl().write_value(scl.psel_bits()); |
| 172 | 160 | ||
| 173 | // Enable TWIM instance. | 161 | // Enable TWIM instance. |
| 174 | r.enable.write(|w| w.enable().enabled()); | 162 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 175 | 163 | ||
| 176 | let mut twim = Self { _p: twim }; | 164 | let mut twim = Self { _p: twim }; |
| 177 | 165 | ||
| @@ -179,7 +167,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 179 | Self::set_config(&mut twim, &config).unwrap(); | 167 | Self::set_config(&mut twim, &config).unwrap(); |
| 180 | 168 | ||
| 181 | // Disable all events interrupts | 169 | // Disable all events interrupts |
| 182 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 170 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 183 | 171 | ||
| 184 | T::Interrupt::unpend(); | 172 | T::Interrupt::unpend(); |
| 185 | unsafe { T::Interrupt::enable() }; | 173 | unsafe { T::Interrupt::enable() }; |
| @@ -211,22 +199,18 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 211 | 199 | ||
| 212 | let r = T::regs(); | 200 | let r = T::regs(); |
| 213 | 201 | ||
| 214 | r.txd.ptr.write(|w| | 202 | // We're giving the register a pointer to the stack. Since we're |
| 215 | // We're giving the register a pointer to the stack. Since we're | 203 | // waiting for the I2C transaction to end before this stack pointer |
| 216 | // waiting for the I2C transaction to end before this stack pointer | 204 | // becomes invalid, there's nothing wrong here. |
| 217 | // becomes invalid, there's nothing wrong here. | 205 | r.txd().ptr().write_value(buffer.as_ptr() as u32); |
| 218 | // | 206 | r.txd().maxcnt().write(|w| |
| 219 | // The PTR field is a full 32 bits wide and accepts the full range | ||
| 220 | // of values. | ||
| 221 | w.ptr().bits(buffer.as_ptr() as u32)); | ||
| 222 | r.txd.maxcnt.write(|w| | ||
| 223 | // We're giving it the length of the buffer, so no danger of | 207 | // We're giving it the length of the buffer, so no danger of |
| 224 | // accessing invalid memory. We have verified that the length of the | 208 | // accessing invalid memory. We have verified that the length of the |
| 225 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | 209 | // buffer fits in an `u8`, so the cast to `u8` is also fine. |
| 226 | // | 210 | // |
| 227 | // The MAXCNT field is 8 bits wide and accepts the full range of | 211 | // The MAXCNT field is 8 bits wide and accepts the full range of |
| 228 | // values. | 212 | // values. |
| 229 | w.maxcnt().bits(buffer.len() as _)); | 213 | w.set_maxcnt(buffer.len() as _)); |
| 230 | 214 | ||
| 231 | Ok(()) | 215 | Ok(()) |
| 232 | } | 216 | } |
| @@ -242,15 +226,11 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 242 | 226 | ||
| 243 | let r = T::regs(); | 227 | let r = T::regs(); |
| 244 | 228 | ||
| 245 | r.rxd.ptr.write(|w| | 229 | // We're giving the register a pointer to the stack. Since we're |
| 246 | // We're giving the register a pointer to the stack. Since we're | 230 | // waiting for the I2C transaction to end before this stack pointer |
| 247 | // waiting for the I2C transaction to end before this stack pointer | 231 | // becomes invalid, there's nothing wrong here. |
| 248 | // becomes invalid, there's nothing wrong here. | 232 | r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32); |
| 249 | // | 233 | r.rxd().maxcnt().write(|w| |
| 250 | // The PTR field is a full 32 bits wide and accepts the full range | ||
| 251 | // of values. | ||
| 252 | w.ptr().bits(buffer.as_mut_ptr() as u32)); | ||
| 253 | r.rxd.maxcnt.write(|w| | ||
| 254 | // We're giving it the length of the buffer, so no danger of | 234 | // We're giving it the length of the buffer, so no danger of |
| 255 | // accessing invalid memory. We have verified that the length of the | 235 | // accessing invalid memory. We have verified that the length of the |
| 256 | // buffer fits in an `u8`, so the cast to the type of maxcnt | 236 | // buffer fits in an `u8`, so the cast to the type of maxcnt |
| @@ -260,29 +240,32 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 260 | // type than a u8, so we use a `_` cast rather than a `u8` cast. | 240 | // type than a u8, so we use a `_` cast rather than a `u8` cast. |
| 261 | // The MAXCNT field is thus at least 8 bits wide and accepts the | 241 | // The MAXCNT field is thus at least 8 bits wide and accepts the |
| 262 | // full range of values that fit in a `u8`. | 242 | // full range of values that fit in a `u8`. |
| 263 | w.maxcnt().bits(buffer.len() as _)); | 243 | w.set_maxcnt(buffer.len() as _)); |
| 264 | 244 | ||
| 265 | Ok(()) | 245 | Ok(()) |
| 266 | } | 246 | } |
| 267 | 247 | ||
| 268 | fn clear_errorsrc(&mut self) { | 248 | fn clear_errorsrc(&mut self) { |
| 269 | let r = T::regs(); | 249 | let r = T::regs(); |
| 270 | r.errorsrc | 250 | r.errorsrc().write(|w| { |
| 271 | .write(|w| w.anack().bit(true).dnack().bit(true).overrun().bit(true)); | 251 | w.set_anack(true); |
| 252 | w.set_dnack(true); | ||
| 253 | w.set_overrun(true); | ||
| 254 | }); | ||
| 272 | } | 255 | } |
| 273 | 256 | ||
| 274 | /// Get Error instance, if any occurred. | 257 | /// Get Error instance, if any occurred. |
| 275 | fn check_errorsrc(&self) -> Result<(), Error> { | 258 | fn check_errorsrc(&self) -> Result<(), Error> { |
| 276 | let r = T::regs(); | 259 | let r = T::regs(); |
| 277 | 260 | ||
| 278 | let err = r.errorsrc.read(); | 261 | let err = r.errorsrc().read(); |
| 279 | if err.anack().is_received() { | 262 | if err.anack() { |
| 280 | return Err(Error::AddressNack); | 263 | return Err(Error::AddressNack); |
| 281 | } | 264 | } |
| 282 | if err.dnack().is_received() { | 265 | if err.dnack() { |
| 283 | return Err(Error::DataNack); | 266 | return Err(Error::DataNack); |
| 284 | } | 267 | } |
| 285 | if err.overrun().is_received() { | 268 | if err.overrun() { |
| 286 | return Err(Error::Overrun); | 269 | return Err(Error::Overrun); |
| 287 | } | 270 | } |
| 288 | Ok(()) | 271 | Ok(()) |
| @@ -290,7 +273,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 290 | 273 | ||
| 291 | fn check_rx(&self, len: usize) -> Result<(), Error> { | 274 | fn check_rx(&self, len: usize) -> Result<(), Error> { |
| 292 | let r = T::regs(); | 275 | let r = T::regs(); |
| 293 | if r.rxd.amount.read().bits() != len as u32 { | 276 | if r.rxd().amount().read().0 != len as u32 { |
| 294 | Err(Error::Receive) | 277 | Err(Error::Receive) |
| 295 | } else { | 278 | } else { |
| 296 | Ok(()) | 279 | Ok(()) |
| @@ -299,7 +282,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 299 | 282 | ||
| 300 | fn check_tx(&self, len: usize) -> Result<(), Error> { | 283 | fn check_tx(&self, len: usize) -> Result<(), Error> { |
| 301 | let r = T::regs(); | 284 | let r = T::regs(); |
| 302 | if r.txd.amount.read().bits() != len as u32 { | 285 | if r.txd().amount().read().0 != len as u32 { |
| 303 | Err(Error::Transmit) | 286 | Err(Error::Transmit) |
| 304 | } else { | 287 | } else { |
| 305 | Ok(()) | 288 | Ok(()) |
| @@ -310,14 +293,14 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 310 | fn blocking_wait(&mut self) { | 293 | fn blocking_wait(&mut self) { |
| 311 | let r = T::regs(); | 294 | let r = T::regs(); |
| 312 | loop { | 295 | loop { |
| 313 | if r.events_suspended.read().bits() != 0 || r.events_stopped.read().bits() != 0 { | 296 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| 314 | r.events_suspended.reset(); | 297 | r.events_suspended().write_value(0); |
| 315 | r.events_stopped.reset(); | 298 | r.events_stopped().write_value(0); |
| 316 | break; | 299 | break; |
| 317 | } | 300 | } |
| 318 | if r.events_error.read().bits() != 0 { | 301 | if r.events_error().read() != 0 { |
| 319 | r.events_error.reset(); | 302 | r.events_error().write_value(0); |
| 320 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 303 | r.tasks_stop().write_value(1); |
| 321 | } | 304 | } |
| 322 | } | 305 | } |
| 323 | } | 306 | } |
| @@ -328,16 +311,16 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 328 | let r = T::regs(); | 311 | let r = T::regs(); |
| 329 | let deadline = Instant::now() + timeout; | 312 | let deadline = Instant::now() + timeout; |
| 330 | loop { | 313 | loop { |
| 331 | if r.events_suspended.read().bits() != 0 || r.events_stopped.read().bits() != 0 { | 314 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| 332 | r.events_stopped.reset(); | 315 | r.events_stopped().write_value(0); |
| 333 | break; | 316 | break; |
| 334 | } | 317 | } |
| 335 | if r.events_error.read().bits() != 0 { | 318 | if r.events_error().read() != 0 { |
| 336 | r.events_error.reset(); | 319 | r.events_error().write_value(0); |
| 337 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 320 | r.tasks_stop().write_value(1); |
| 338 | } | 321 | } |
| 339 | if Instant::now() > deadline { | 322 | if Instant::now() > deadline { |
| 340 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 323 | r.tasks_stop().write_value(1); |
| 341 | return Err(Error::Timeout); | 324 | return Err(Error::Timeout); |
| 342 | } | 325 | } |
| 343 | } | 326 | } |
| @@ -352,16 +335,16 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 352 | let s = T::state(); | 335 | let s = T::state(); |
| 353 | 336 | ||
| 354 | s.end_waker.register(cx.waker()); | 337 | s.end_waker.register(cx.waker()); |
| 355 | if r.events_suspended.read().bits() != 0 || r.events_stopped.read().bits() != 0 { | 338 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| 356 | r.events_stopped.reset(); | 339 | r.events_stopped().write_value(0); |
| 357 | 340 | ||
| 358 | return Poll::Ready(()); | 341 | return Poll::Ready(()); |
| 359 | } | 342 | } |
| 360 | 343 | ||
| 361 | // stop if an error occurred | 344 | // stop if an error occurred |
| 362 | if r.events_error.read().bits() != 0 { | 345 | if r.events_error().read() != 0 { |
| 363 | r.events_error.reset(); | 346 | r.events_error().write_value(0); |
| 364 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 347 | r.tasks_stop().write_value(1); |
| 365 | } | 348 | } |
| 366 | 349 | ||
| 367 | Poll::Pending | 350 | Poll::Pending |
| @@ -380,18 +363,25 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 380 | 363 | ||
| 381 | compiler_fence(SeqCst); | 364 | compiler_fence(SeqCst); |
| 382 | 365 | ||
| 383 | r.address.write(|w| unsafe { w.address().bits(address) }); | 366 | r.address().write(|w| w.set_address(address)); |
| 384 | 367 | ||
| 385 | r.events_suspended.reset(); | 368 | r.events_suspended().write_value(0); |
| 386 | r.events_stopped.reset(); | 369 | r.events_stopped().write_value(0); |
| 387 | r.events_error.reset(); | 370 | r.events_error().write_value(0); |
| 388 | self.clear_errorsrc(); | 371 | self.clear_errorsrc(); |
| 389 | 372 | ||
| 390 | if inten { | 373 | if inten { |
| 391 | r.intenset.write(|w| w.suspended().set().stopped().set().error().set()); | 374 | r.intenset().write(|w| { |
| 375 | w.set_suspended(true); | ||
| 376 | w.set_stopped(true); | ||
| 377 | w.set_error(true); | ||
| 378 | }); | ||
| 392 | } else { | 379 | } else { |
| 393 | r.intenclr | 380 | r.intenclr().write(|w| { |
| 394 | .write(|w| w.suspended().clear().stopped().clear().error().clear()); | 381 | w.set_suspended(true); |
| 382 | w.set_stopped(true); | ||
| 383 | w.set_error(true); | ||
| 384 | }); | ||
| 395 | } | 385 | } |
| 396 | 386 | ||
| 397 | assert!(!operations.is_empty()); | 387 | assert!(!operations.is_empty()); |
| @@ -408,26 +398,25 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 408 | self.set_rx_buffer(rd_buffer)?; | 398 | self.set_rx_buffer(rd_buffer)?; |
| 409 | } | 399 | } |
| 410 | 400 | ||
| 411 | r.shorts.write(|w| { | 401 | r.shorts().write(|w| { |
| 412 | w.lastrx_starttx().enabled(); | 402 | w.set_lastrx_starttx(true); |
| 413 | if stop { | 403 | if stop { |
| 414 | w.lasttx_stop().enabled(); | 404 | w.set_lasttx_stop(true); |
| 415 | } else { | 405 | } else { |
| 416 | w.lasttx_suspend().enabled(); | 406 | w.set_lasttx_suspend(true); |
| 417 | } | 407 | } |
| 418 | w | ||
| 419 | }); | 408 | }); |
| 420 | 409 | ||
| 421 | // Start read+write operation. | 410 | // Start read+write operation. |
| 422 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 411 | r.tasks_startrx().write_value(1); |
| 423 | if last_op.is_some() { | 412 | if last_op.is_some() { |
| 424 | r.tasks_resume.write(|w| unsafe { w.bits(1) }); | 413 | r.tasks_resume().write_value(1); |
| 425 | } | 414 | } |
| 426 | 415 | ||
| 427 | // TODO: Handle empty write buffer | 416 | // TODO: Handle empty write buffer |
| 428 | if rd_buffer.is_empty() { | 417 | if rd_buffer.is_empty() { |
| 429 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves. | 418 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves. |
| 430 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 419 | r.tasks_starttx().write_value(1); |
| 431 | } | 420 | } |
| 432 | 421 | ||
| 433 | Ok(2) | 422 | Ok(2) |
| @@ -438,17 +427,17 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 438 | self.set_rx_buffer(buffer)?; | 427 | self.set_rx_buffer(buffer)?; |
| 439 | } | 428 | } |
| 440 | 429 | ||
| 441 | r.shorts.write(|w| w.lastrx_stop().enabled()); | 430 | r.shorts().write(|w| w.set_lastrx_stop(true)); |
| 442 | 431 | ||
| 443 | // Start read operation. | 432 | // Start read operation. |
| 444 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 433 | r.tasks_startrx().write_value(1); |
| 445 | if last_op.is_some() { | 434 | if last_op.is_some() { |
| 446 | r.tasks_resume.write(|w| unsafe { w.bits(1) }); | 435 | r.tasks_resume().write_value(1); |
| 447 | } | 436 | } |
| 448 | 437 | ||
| 449 | if buffer.is_empty() { | 438 | if buffer.is_empty() { |
| 450 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves. | 439 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves. |
| 451 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 440 | r.tasks_stop().write_value(1); |
| 452 | } | 441 | } |
| 453 | 442 | ||
| 454 | Ok(1) | 443 | Ok(1) |
| @@ -463,15 +452,14 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 463 | } | 452 | } |
| 464 | 453 | ||
| 465 | // Start write+read operation. | 454 | // Start write+read operation. |
| 466 | r.shorts.write(|w| { | 455 | r.shorts().write(|w| { |
| 467 | w.lasttx_startrx().enabled(); | 456 | w.set_lasttx_startrx(true); |
| 468 | w.lastrx_stop().enabled(); | 457 | w.set_lastrx_stop(true); |
| 469 | w | ||
| 470 | }); | 458 | }); |
| 471 | 459 | ||
| 472 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 460 | r.tasks_starttx().write_value(1); |
| 473 | if last_op.is_some() { | 461 | if last_op.is_some() { |
| 474 | r.tasks_resume.write(|w| unsafe { w.bits(1) }); | 462 | r.tasks_resume().write_value(1); |
| 475 | } | 463 | } |
| 476 | 464 | ||
| 477 | Ok(2) | 465 | Ok(2) |
| @@ -485,26 +473,25 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 485 | } | 473 | } |
| 486 | 474 | ||
| 487 | // Start write operation. | 475 | // Start write operation. |
| 488 | r.shorts.write(|w| { | 476 | r.shorts().write(|w| { |
| 489 | if stop { | 477 | if stop { |
| 490 | w.lasttx_stop().enabled(); | 478 | w.set_lasttx_stop(true); |
| 491 | } else { | 479 | } else { |
| 492 | w.lasttx_suspend().enabled(); | 480 | w.set_lasttx_suspend(true); |
| 493 | } | 481 | } |
| 494 | w | ||
| 495 | }); | 482 | }); |
| 496 | 483 | ||
| 497 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 484 | r.tasks_starttx().write_value(1); |
| 498 | if last_op.is_some() { | 485 | if last_op.is_some() { |
| 499 | r.tasks_resume.write(|w| unsafe { w.bits(1) }); | 486 | r.tasks_resume().write_value(1); |
| 500 | } | 487 | } |
| 501 | 488 | ||
| 502 | if buffer.is_empty() { | 489 | if buffer.is_empty() { |
| 503 | // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP/SUSPEND ourselves. | 490 | // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP/SUSPEND ourselves. |
| 504 | if stop { | 491 | if stop { |
| 505 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 492 | r.tasks_stop().write_value(1); |
| 506 | } else { | 493 | } else { |
| 507 | r.tasks_suspend.write(|w| unsafe { w.bits(1) }); | 494 | r.tasks_suspend().write_value(1); |
| 508 | } | 495 | } |
| 509 | } | 496 | } |
| 510 | 497 | ||
| @@ -827,10 +814,10 @@ impl<'a, T: Instance> Drop for Twim<'a, T> { | |||
| 827 | 814 | ||
| 828 | // disable! | 815 | // disable! |
| 829 | let r = T::regs(); | 816 | let r = T::regs(); |
| 830 | r.enable.write(|w| w.enable().disabled()); | 817 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 831 | 818 | ||
| 832 | gpio::deconfigure_pin(r.psel.sda.read().bits()); | 819 | gpio::deconfigure_pin(r.psel().sda().read()); |
| 833 | gpio::deconfigure_pin(r.psel.scl.read().bits()); | 820 | gpio::deconfigure_pin(r.psel().scl().read()); |
| 834 | 821 | ||
| 835 | trace!("twim drop: done"); | 822 | trace!("twim drop: done"); |
| 836 | } | 823 | } |
| @@ -849,7 +836,7 @@ impl State { | |||
| 849 | } | 836 | } |
| 850 | 837 | ||
| 851 | pub(crate) trait SealedInstance { | 838 | pub(crate) trait SealedInstance { |
| 852 | fn regs() -> &'static pac::twim0::RegisterBlock; | 839 | fn regs() -> pac::twim::Twim; |
| 853 | fn state() -> &'static State; | 840 | fn state() -> &'static State; |
| 854 | } | 841 | } |
| 855 | 842 | ||
| @@ -863,8 +850,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { | |||
| 863 | macro_rules! impl_twim { | 850 | macro_rules! impl_twim { |
| 864 | ($type:ident, $pac_type:ident, $irq:ident) => { | 851 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 865 | impl crate::twim::SealedInstance for peripherals::$type { | 852 | impl crate::twim::SealedInstance for peripherals::$type { |
| 866 | fn regs() -> &'static pac::twim0::RegisterBlock { | 853 | fn regs() -> pac::twim::Twim { |
| 867 | unsafe { &*pac::$pac_type::ptr() } | 854 | pac::$pac_type |
| 868 | } | 855 | } |
| 869 | fn state() -> &'static crate::twim::State { | 856 | fn state() -> &'static crate::twim::State { |
| 870 | static STATE: crate::twim::State = crate::twim::State::new(); | 857 | static STATE: crate::twim::State = crate::twim::State::new(); |
| @@ -948,8 +935,7 @@ impl<'d, T: Instance> SetConfig for Twim<'d, T> { | |||
| 948 | type ConfigError = (); | 935 | type ConfigError = (); |
| 949 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { | 936 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { |
| 950 | let r = T::regs(); | 937 | let r = T::regs(); |
| 951 | r.frequency | 938 | r.frequency().write(|w| w.set_frequency(config.frequency)); |
| 952 | .write(|w| unsafe { w.frequency().bits(config.frequency as u32) }); | ||
| 953 | 939 | ||
| 954 | Ok(()) | 940 | Ok(()) |
| 955 | } | 941 | } |
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index f3eab008f..60de2ed9d 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs | |||
| @@ -16,6 +16,8 @@ use embassy_time::{Duration, Instant}; | |||
| 16 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 16 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 17 | use crate::gpio::Pin as GpioPin; | 17 | use crate::gpio::Pin as GpioPin; |
| 18 | use crate::interrupt::typelevel::Interrupt; | 18 | use crate::interrupt::typelevel::Interrupt; |
| 19 | use crate::pac::gpio::vals as gpiovals; | ||
| 20 | use crate::pac::twis::vals; | ||
| 19 | use crate::util::slice_in_ram_or; | 21 | use crate::util::slice_in_ram_or; |
| 20 | use crate::{gpio, interrupt, pac, Peripheral}; | 22 | use crate::{gpio, interrupt, pac, Peripheral}; |
| 21 | 23 | ||
| @@ -119,17 +121,20 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 119 | let r = T::regs(); | 121 | let r = T::regs(); |
| 120 | let s = T::state(); | 122 | let s = T::state(); |
| 121 | 123 | ||
| 122 | if r.events_read.read().bits() != 0 || r.events_write.read().bits() != 0 { | 124 | if r.events_read().read() != 0 || r.events_write().read() != 0 { |
| 123 | s.waker.wake(); | 125 | s.waker.wake(); |
| 124 | r.intenclr.modify(|_r, w| w.read().clear().write().clear()); | 126 | r.intenclr().write(|w| { |
| 127 | w.set_read(true); | ||
| 128 | w.set_write(true); | ||
| 129 | }); | ||
| 125 | } | 130 | } |
| 126 | if r.events_stopped.read().bits() != 0 { | 131 | if r.events_stopped().read() != 0 { |
| 127 | s.waker.wake(); | 132 | s.waker.wake(); |
| 128 | r.intenclr.modify(|_r, w| w.stopped().clear()); | 133 | r.intenclr().write(|w| w.set_stopped(true)); |
| 129 | } | 134 | } |
| 130 | if r.events_error.read().bits() != 0 { | 135 | if r.events_error().read() != 0 { |
| 131 | s.waker.wake(); | 136 | s.waker.wake(); |
| 132 | r.intenclr.modify(|_r, w| w.error().clear()); | 137 | r.intenclr().write(|w| w.set_error(true)); |
| 133 | } | 138 | } |
| 134 | } | 139 | } |
| 135 | } | 140 | } |
| @@ -154,55 +159,51 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 154 | 159 | ||
| 155 | // Configure pins | 160 | // Configure pins |
| 156 | sda.conf().write(|w| { | 161 | sda.conf().write(|w| { |
| 157 | w.dir().input(); | 162 | w.set_dir(gpiovals::Dir::INPUT); |
| 158 | w.input().connect(); | 163 | w.set_input(gpiovals::Input::CONNECT); |
| 159 | if config.sda_high_drive { | 164 | w.set_drive(match config.sda_high_drive { |
| 160 | w.drive().h0d1(); | 165 | true => gpiovals::Drive::H0D1, |
| 161 | } else { | 166 | false => gpiovals::Drive::S0D1, |
| 162 | w.drive().s0d1(); | 167 | }); |
| 163 | } | ||
| 164 | if config.sda_pullup { | 168 | if config.sda_pullup { |
| 165 | w.pull().pullup(); | 169 | w.set_pull(gpiovals::Pull::PULLUP); |
| 166 | } | 170 | } |
| 167 | w | ||
| 168 | }); | 171 | }); |
| 169 | scl.conf().write(|w| { | 172 | scl.conf().write(|w| { |
| 170 | w.dir().input(); | 173 | w.set_dir(gpiovals::Dir::INPUT); |
| 171 | w.input().connect(); | 174 | w.set_input(gpiovals::Input::CONNECT); |
| 172 | if config.scl_high_drive { | 175 | w.set_drive(match config.scl_high_drive { |
| 173 | w.drive().h0d1(); | 176 | true => gpiovals::Drive::H0D1, |
| 174 | } else { | 177 | false => gpiovals::Drive::S0D1, |
| 175 | w.drive().s0d1(); | 178 | }); |
| 176 | } | 179 | if config.sda_pullup { |
| 177 | if config.scl_pullup { | 180 | w.set_pull(gpiovals::Pull::PULLUP); |
| 178 | w.pull().pullup(); | ||
| 179 | } | 181 | } |
| 180 | w | ||
| 181 | }); | 182 | }); |
| 182 | 183 | ||
| 183 | // Select pins. | 184 | // Select pins. |
| 184 | r.psel.sda.write(|w| unsafe { w.bits(sda.psel_bits()) }); | 185 | r.psel().sda().write_value(sda.psel_bits()); |
| 185 | r.psel.scl.write(|w| unsafe { w.bits(scl.psel_bits()) }); | 186 | r.psel().scl().write_value(scl.psel_bits()); |
| 186 | 187 | ||
| 187 | // Enable TWIS instance. | 188 | // Enable TWIS instance. |
| 188 | r.enable.write(|w| w.enable().enabled()); | 189 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 189 | 190 | ||
| 190 | // Disable all events interrupts | 191 | // Disable all events interrupts |
| 191 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 192 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 192 | 193 | ||
| 193 | // Set address | 194 | // Set address |
| 194 | r.address[0].write(|w| unsafe { w.address().bits(config.address0) }); | 195 | r.address(0).write(|w| w.set_address(config.address0)); |
| 195 | r.config.write(|w| w.address0().enabled()); | 196 | r.config().write(|w| w.set_address0(true)); |
| 196 | if let Some(address1) = config.address1 { | 197 | if let Some(address1) = config.address1 { |
| 197 | r.address[1].write(|w| unsafe { w.address().bits(address1) }); | 198 | r.address(1).write(|w| w.set_address(address1)); |
| 198 | r.config.modify(|_r, w| w.address1().enabled()); | 199 | r.config().modify(|w| w.set_address1(true)); |
| 199 | } | 200 | } |
| 200 | 201 | ||
| 201 | // Set over-read character | 202 | // Set over-read character |
| 202 | r.orc.write(|w| unsafe { w.orc().bits(config.orc) }); | 203 | r.orc().write(|w| w.set_orc(config.orc)); |
| 203 | 204 | ||
| 204 | // Generate suspend on read event | 205 | // Generate suspend on read event |
| 205 | r.shorts.write(|w| w.read_suspend().enabled()); | 206 | r.shorts().write(|w| w.set_read_suspend(true)); |
| 206 | 207 | ||
| 207 | T::Interrupt::unpend(); | 208 | T::Interrupt::unpend(); |
| 208 | unsafe { T::Interrupt::enable() }; | 209 | unsafe { T::Interrupt::enable() }; |
| @@ -220,22 +221,18 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 220 | 221 | ||
| 221 | let r = T::regs(); | 222 | let r = T::regs(); |
| 222 | 223 | ||
| 223 | r.txd.ptr.write(|w| | 224 | // We're giving the register a pointer to the stack. Since we're |
| 224 | // We're giving the register a pointer to the stack. Since we're | 225 | // waiting for the I2C transaction to end before this stack pointer |
| 225 | // waiting for the I2C transaction to end before this stack pointer | 226 | // becomes invalid, there's nothing wrong here. |
| 226 | // becomes invalid, there's nothing wrong here. | 227 | r.txd().ptr().write_value(buffer.as_ptr() as u32); |
| 227 | // | 228 | r.txd().maxcnt().write(|w| |
| 228 | // The PTR field is a full 32 bits wide and accepts the full range | ||
| 229 | // of values. | ||
| 230 | w.ptr().bits(buffer.as_ptr() as u32)); | ||
| 231 | r.txd.maxcnt.write(|w| | ||
| 232 | // We're giving it the length of the buffer, so no danger of | 229 | // We're giving it the length of the buffer, so no danger of |
| 233 | // accessing invalid memory. We have verified that the length of the | 230 | // accessing invalid memory. We have verified that the length of the |
| 234 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | 231 | // buffer fits in an `u8`, so the cast to `u8` is also fine. |
| 235 | // | 232 | // |
| 236 | // The MAXCNT field is 8 bits wide and accepts the full range of | 233 | // The MAXCNT field is 8 bits wide and accepts the full range of |
| 237 | // values. | 234 | // values. |
| 238 | w.maxcnt().bits(buffer.len() as _)); | 235 | w.set_maxcnt(buffer.len() as _)); |
| 239 | 236 | ||
| 240 | Ok(()) | 237 | Ok(()) |
| 241 | } | 238 | } |
| @@ -251,15 +248,11 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 251 | 248 | ||
| 252 | let r = T::regs(); | 249 | let r = T::regs(); |
| 253 | 250 | ||
| 254 | r.rxd.ptr.write(|w| | 251 | // We're giving the register a pointer to the stack. Since we're |
| 255 | // We're giving the register a pointer to the stack. Since we're | 252 | // waiting for the I2C transaction to end before this stack pointer |
| 256 | // waiting for the I2C transaction to end before this stack pointer | 253 | // becomes invalid, there's nothing wrong here. |
| 257 | // becomes invalid, there's nothing wrong here. | 254 | r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32); |
| 258 | // | 255 | r.rxd().maxcnt().write(|w| |
| 259 | // The PTR field is a full 32 bits wide and accepts the full range | ||
| 260 | // of values. | ||
| 261 | w.ptr().bits(buffer.as_mut_ptr() as u32)); | ||
| 262 | r.rxd.maxcnt.write(|w| | ||
| 263 | // We're giving it the length of the buffer, so no danger of | 256 | // We're giving it the length of the buffer, so no danger of |
| 264 | // accessing invalid memory. We have verified that the length of the | 257 | // accessing invalid memory. We have verified that the length of the |
| 265 | // buffer fits in an `u8`, so the cast to the type of maxcnt | 258 | // buffer fits in an `u8`, so the cast to the type of maxcnt |
| @@ -269,48 +262,51 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 269 | // type than a u8, so we use a `_` cast rather than a `u8` cast. | 262 | // type than a u8, so we use a `_` cast rather than a `u8` cast. |
| 270 | // The MAXCNT field is thus at least 8 bits wide and accepts the | 263 | // The MAXCNT field is thus at least 8 bits wide and accepts the |
| 271 | // full range of values that fit in a `u8`. | 264 | // full range of values that fit in a `u8`. |
| 272 | w.maxcnt().bits(buffer.len() as _)); | 265 | w.set_maxcnt(buffer.len() as _)); |
| 273 | 266 | ||
| 274 | Ok(()) | 267 | Ok(()) |
| 275 | } | 268 | } |
| 276 | 269 | ||
| 277 | fn clear_errorsrc(&mut self) { | 270 | fn clear_errorsrc(&mut self) { |
| 278 | let r = T::regs(); | 271 | let r = T::regs(); |
| 279 | r.errorsrc | 272 | r.errorsrc().write(|w| { |
| 280 | .write(|w| w.overflow().bit(true).overread().bit(true).dnack().bit(true)); | 273 | w.set_overflow(true); |
| 274 | w.set_overread(true); | ||
| 275 | w.set_dnack(true); | ||
| 276 | }); | ||
| 281 | } | 277 | } |
| 282 | 278 | ||
| 283 | /// Returns matched address for latest command. | 279 | /// Returns matched address for latest command. |
| 284 | pub fn address_match(&self) -> u8 { | 280 | pub fn address_match(&self) -> u8 { |
| 285 | let r = T::regs(); | 281 | let r = T::regs(); |
| 286 | r.address[r.match_.read().bits() as usize].read().address().bits() | 282 | r.address(r.match_().read().0 as usize).read().address() |
| 287 | } | 283 | } |
| 288 | 284 | ||
| 289 | /// Returns the index of the address matched in the latest command. | 285 | /// Returns the index of the address matched in the latest command. |
| 290 | pub fn address_match_index(&self) -> usize { | 286 | pub fn address_match_index(&self) -> usize { |
| 291 | T::regs().match_.read().bits() as _ | 287 | T::regs().match_().read().0 as _ |
| 292 | } | 288 | } |
| 293 | 289 | ||
| 294 | /// Wait for read, write, stop or error | 290 | /// Wait for read, write, stop or error |
| 295 | fn blocking_listen_wait(&mut self) -> Result<Status, Error> { | 291 | fn blocking_listen_wait(&mut self) -> Result<Status, Error> { |
| 296 | let r = T::regs(); | 292 | let r = T::regs(); |
| 297 | loop { | 293 | loop { |
| 298 | if r.events_error.read().bits() != 0 { | 294 | if r.events_error().read() != 0 { |
| 299 | r.events_error.reset(); | 295 | r.events_error().write_value(0); |
| 300 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 296 | r.tasks_stop().write_value(1); |
| 301 | while r.events_stopped.read().bits() == 0 {} | 297 | while r.events_stopped().read() == 0 {} |
| 302 | return Err(Error::Overflow); | 298 | return Err(Error::Overflow); |
| 303 | } | 299 | } |
| 304 | if r.events_stopped.read().bits() != 0 { | 300 | if r.events_stopped().read() != 0 { |
| 305 | r.events_stopped.reset(); | 301 | r.events_stopped().write_value(0); |
| 306 | return Err(Error::Bus); | 302 | return Err(Error::Bus); |
| 307 | } | 303 | } |
| 308 | if r.events_read.read().bits() != 0 { | 304 | if r.events_read().read() != 0 { |
| 309 | r.events_read.reset(); | 305 | r.events_read().write_value(0); |
| 310 | return Ok(Status::Read); | 306 | return Ok(Status::Read); |
| 311 | } | 307 | } |
| 312 | if r.events_write.read().bits() != 0 { | 308 | if r.events_write().read() != 0 { |
| 313 | r.events_write.reset(); | 309 | r.events_write().write_value(0); |
| 314 | return Ok(Status::Write); | 310 | return Ok(Status::Write); |
| 315 | } | 311 | } |
| 316 | } | 312 | } |
| @@ -321,22 +317,22 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 321 | let r = T::regs(); | 317 | let r = T::regs(); |
| 322 | loop { | 318 | loop { |
| 323 | // stop if an error occurred | 319 | // stop if an error occurred |
| 324 | if r.events_error.read().bits() != 0 { | 320 | if r.events_error().read() != 0 { |
| 325 | r.events_error.reset(); | 321 | r.events_error().write_value(0); |
| 326 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 322 | r.tasks_stop().write_value(1); |
| 327 | return Err(Error::Overflow); | 323 | return Err(Error::Overflow); |
| 328 | } else if r.events_stopped.read().bits() != 0 { | 324 | } else if r.events_stopped().read() != 0 { |
| 329 | r.events_stopped.reset(); | 325 | r.events_stopped().write_value(0); |
| 330 | return match status { | 326 | return match status { |
| 331 | Status::Read => Ok(Command::Read), | 327 | Status::Read => Ok(Command::Read), |
| 332 | Status::Write => { | 328 | Status::Write => { |
| 333 | let n = r.rxd.amount.read().bits() as usize; | 329 | let n = r.rxd().amount().read().0 as usize; |
| 334 | Ok(Command::Write(n)) | 330 | Ok(Command::Write(n)) |
| 335 | } | 331 | } |
| 336 | }; | 332 | }; |
| 337 | } else if r.events_read.read().bits() != 0 { | 333 | } else if r.events_read().read() != 0 { |
| 338 | r.events_read.reset(); | 334 | r.events_read().write_value(0); |
| 339 | let n = r.rxd.amount.read().bits() as usize; | 335 | let n = r.rxd().amount().read().0 as usize; |
| 340 | return Ok(Command::WriteRead(n)); | 336 | return Ok(Command::WriteRead(n)); |
| 341 | } | 337 | } |
| 342 | } | 338 | } |
| @@ -347,20 +343,20 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 347 | let r = T::regs(); | 343 | let r = T::regs(); |
| 348 | loop { | 344 | loop { |
| 349 | // stop if an error occurred | 345 | // stop if an error occurred |
| 350 | if r.events_error.read().bits() != 0 { | 346 | if r.events_error().read() != 0 { |
| 351 | r.events_error.reset(); | 347 | r.events_error().write_value(0); |
| 352 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 348 | r.tasks_stop().write_value(1); |
| 353 | let errorsrc = r.errorsrc.read(); | 349 | let errorsrc = r.errorsrc().read(); |
| 354 | if errorsrc.overread().is_detected() { | 350 | if errorsrc.overread() { |
| 355 | return Err(Error::OverRead); | 351 | return Err(Error::OverRead); |
| 356 | } else if errorsrc.dnack().is_received() { | 352 | } else if errorsrc.dnack() { |
| 357 | return Err(Error::DataNack); | 353 | return Err(Error::DataNack); |
| 358 | } else { | 354 | } else { |
| 359 | return Err(Error::Bus); | 355 | return Err(Error::Bus); |
| 360 | } | 356 | } |
| 361 | } else if r.events_stopped.read().bits() != 0 { | 357 | } else if r.events_stopped().read() != 0 { |
| 362 | r.events_stopped.reset(); | 358 | r.events_stopped().write_value(0); |
| 363 | let n = r.txd.amount.read().bits() as usize; | 359 | let n = r.txd().amount().read().0 as usize; |
| 364 | return Ok(n); | 360 | return Ok(n); |
| 365 | } | 361 | } |
| 366 | } | 362 | } |
| @@ -373,23 +369,23 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 373 | let deadline = Instant::now() + timeout; | 369 | let deadline = Instant::now() + timeout; |
| 374 | loop { | 370 | loop { |
| 375 | // stop if an error occurred | 371 | // stop if an error occurred |
| 376 | if r.events_error.read().bits() != 0 { | 372 | if r.events_error().read() != 0 { |
| 377 | r.events_error.reset(); | 373 | r.events_error().write_value(0); |
| 378 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 374 | r.tasks_stop().write_value(1); |
| 379 | let errorsrc = r.errorsrc.read(); | 375 | let errorsrc = r.errorsrc().read(); |
| 380 | if errorsrc.overread().is_detected() { | 376 | if errorsrc.overread() { |
| 381 | return Err(Error::OverRead); | 377 | return Err(Error::OverRead); |
| 382 | } else if errorsrc.dnack().is_received() { | 378 | } else if errorsrc.dnack() { |
| 383 | return Err(Error::DataNack); | 379 | return Err(Error::DataNack); |
| 384 | } else { | 380 | } else { |
| 385 | return Err(Error::Bus); | 381 | return Err(Error::Bus); |
| 386 | } | 382 | } |
| 387 | } else if r.events_stopped.read().bits() != 0 { | 383 | } else if r.events_stopped().read() != 0 { |
| 388 | r.events_stopped.reset(); | 384 | r.events_stopped().write_value(0); |
| 389 | let n = r.txd.amount.read().bits() as usize; | 385 | let n = r.txd().amount().read().0 as usize; |
| 390 | return Ok(n); | 386 | return Ok(n); |
| 391 | } else if Instant::now() > deadline { | 387 | } else if Instant::now() > deadline { |
| 392 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 388 | r.tasks_stop().write_value(1); |
| 393 | return Err(Error::Timeout); | 389 | return Err(Error::Timeout); |
| 394 | } | 390 | } |
| 395 | } | 391 | } |
| @@ -401,26 +397,26 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 401 | let r = T::regs(); | 397 | let r = T::regs(); |
| 402 | let deadline = Instant::now() + timeout; | 398 | let deadline = Instant::now() + timeout; |
| 403 | loop { | 399 | loop { |
| 404 | if r.events_error.read().bits() != 0 { | 400 | if r.events_error().read() != 0 { |
| 405 | r.events_error.reset(); | 401 | r.events_error().write_value(0); |
| 406 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 402 | r.tasks_stop().write_value(1); |
| 407 | while r.events_stopped.read().bits() == 0 {} | 403 | while r.events_stopped().read() == 0 {} |
| 408 | return Err(Error::Overflow); | 404 | return Err(Error::Overflow); |
| 409 | } | 405 | } |
| 410 | if r.events_stopped.read().bits() != 0 { | 406 | if r.events_stopped().read() != 0 { |
| 411 | r.events_stopped.reset(); | 407 | r.events_stopped().write_value(0); |
| 412 | return Err(Error::Bus); | 408 | return Err(Error::Bus); |
| 413 | } | 409 | } |
| 414 | if r.events_read.read().bits() != 0 { | 410 | if r.events_read().read() != 0 { |
| 415 | r.events_read.reset(); | 411 | r.events_read().write_value(0); |
| 416 | return Ok(Status::Read); | 412 | return Ok(Status::Read); |
| 417 | } | 413 | } |
| 418 | if r.events_write.read().bits() != 0 { | 414 | if r.events_write().read() != 0 { |
| 419 | r.events_write.reset(); | 415 | r.events_write().write_value(0); |
| 420 | return Ok(Status::Write); | 416 | return Ok(Status::Write); |
| 421 | } | 417 | } |
| 422 | if Instant::now() > deadline { | 418 | if Instant::now() > deadline { |
| 423 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 419 | r.tasks_stop().write_value(1); |
| 424 | return Err(Error::Timeout); | 420 | return Err(Error::Timeout); |
| 425 | } | 421 | } |
| 426 | } | 422 | } |
| @@ -433,25 +429,25 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 433 | let deadline = Instant::now() + timeout; | 429 | let deadline = Instant::now() + timeout; |
| 434 | loop { | 430 | loop { |
| 435 | // stop if an error occurred | 431 | // stop if an error occurred |
| 436 | if r.events_error.read().bits() != 0 { | 432 | if r.events_error().read() != 0 { |
| 437 | r.events_error.reset(); | 433 | r.events_error().write_value(0); |
| 438 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 434 | r.tasks_stop().write_value(1); |
| 439 | return Err(Error::Overflow); | 435 | return Err(Error::Overflow); |
| 440 | } else if r.events_stopped.read().bits() != 0 { | 436 | } else if r.events_stopped().read() != 0 { |
| 441 | r.events_stopped.reset(); | 437 | r.events_stopped().write_value(0); |
| 442 | return match status { | 438 | return match status { |
| 443 | Status::Read => Ok(Command::Read), | 439 | Status::Read => Ok(Command::Read), |
| 444 | Status::Write => { | 440 | Status::Write => { |
| 445 | let n = r.rxd.amount.read().bits() as usize; | 441 | let n = r.rxd().amount().read().0 as usize; |
| 446 | Ok(Command::Write(n)) | 442 | Ok(Command::Write(n)) |
| 447 | } | 443 | } |
| 448 | }; | 444 | }; |
| 449 | } else if r.events_read.read().bits() != 0 { | 445 | } else if r.events_read().read() != 0 { |
| 450 | r.events_read.reset(); | 446 | r.events_read().write_value(0); |
| 451 | let n = r.rxd.amount.read().bits() as usize; | 447 | let n = r.rxd().amount().read().0 as usize; |
| 452 | return Ok(Command::WriteRead(n)); | 448 | return Ok(Command::WriteRead(n)); |
| 453 | } else if Instant::now() > deadline { | 449 | } else if Instant::now() > deadline { |
| 454 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 450 | r.tasks_stop().write_value(1); |
| 455 | return Err(Error::Timeout); | 451 | return Err(Error::Timeout); |
| 456 | } | 452 | } |
| 457 | } | 453 | } |
| @@ -466,20 +462,20 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 466 | s.waker.register(cx.waker()); | 462 | s.waker.register(cx.waker()); |
| 467 | 463 | ||
| 468 | // stop if an error occurred | 464 | // stop if an error occurred |
| 469 | if r.events_error.read().bits() != 0 { | 465 | if r.events_error().read() != 0 { |
| 470 | r.events_error.reset(); | 466 | r.events_error().write_value(0); |
| 471 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 467 | r.tasks_stop().write_value(1); |
| 472 | let errorsrc = r.errorsrc.read(); | 468 | let errorsrc = r.errorsrc().read(); |
| 473 | if errorsrc.overread().is_detected() { | 469 | if errorsrc.overread() { |
| 474 | return Poll::Ready(Err(Error::OverRead)); | 470 | return Poll::Ready(Err(Error::OverRead)); |
| 475 | } else if errorsrc.dnack().is_received() { | 471 | } else if errorsrc.dnack() { |
| 476 | return Poll::Ready(Err(Error::DataNack)); | 472 | return Poll::Ready(Err(Error::DataNack)); |
| 477 | } else { | 473 | } else { |
| 478 | return Poll::Ready(Err(Error::Bus)); | 474 | return Poll::Ready(Err(Error::Bus)); |
| 479 | } | 475 | } |
| 480 | } else if r.events_stopped.read().bits() != 0 { | 476 | } else if r.events_stopped().read() != 0 { |
| 481 | r.events_stopped.reset(); | 477 | r.events_stopped().write_value(0); |
| 482 | let n = r.txd.amount.read().bits() as usize; | 478 | let n = r.txd().amount().read().0 as usize; |
| 483 | return Poll::Ready(Ok(n)); | 479 | return Poll::Ready(Ok(n)); |
| 484 | } | 480 | } |
| 485 | 481 | ||
| @@ -496,18 +492,18 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 496 | s.waker.register(cx.waker()); | 492 | s.waker.register(cx.waker()); |
| 497 | 493 | ||
| 498 | // stop if an error occurred | 494 | // stop if an error occurred |
| 499 | if r.events_error.read().bits() != 0 { | 495 | if r.events_error().read() != 0 { |
| 500 | r.events_error.reset(); | 496 | r.events_error().write_value(0); |
| 501 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 497 | r.tasks_stop().write_value(1); |
| 502 | return Poll::Ready(Err(Error::Overflow)); | 498 | return Poll::Ready(Err(Error::Overflow)); |
| 503 | } else if r.events_read.read().bits() != 0 { | 499 | } else if r.events_read().read() != 0 { |
| 504 | r.events_read.reset(); | 500 | r.events_read().write_value(0); |
| 505 | return Poll::Ready(Ok(Status::Read)); | 501 | return Poll::Ready(Ok(Status::Read)); |
| 506 | } else if r.events_write.read().bits() != 0 { | 502 | } else if r.events_write().read() != 0 { |
| 507 | r.events_write.reset(); | 503 | r.events_write().write_value(0); |
| 508 | return Poll::Ready(Ok(Status::Write)); | 504 | return Poll::Ready(Ok(Status::Write)); |
| 509 | } else if r.events_stopped.read().bits() != 0 { | 505 | } else if r.events_stopped().read() != 0 { |
| 510 | r.events_stopped.reset(); | 506 | r.events_stopped().write_value(0); |
| 511 | return Poll::Ready(Err(Error::Bus)); | 507 | return Poll::Ready(Err(Error::Bus)); |
| 512 | } | 508 | } |
| 513 | Poll::Pending | 509 | Poll::Pending |
| @@ -523,22 +519,22 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 523 | s.waker.register(cx.waker()); | 519 | s.waker.register(cx.waker()); |
| 524 | 520 | ||
| 525 | // stop if an error occurred | 521 | // stop if an error occurred |
| 526 | if r.events_error.read().bits() != 0 { | 522 | if r.events_error().read() != 0 { |
| 527 | r.events_error.reset(); | 523 | r.events_error().write_value(0); |
| 528 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | 524 | r.tasks_stop().write_value(1); |
| 529 | return Poll::Ready(Err(Error::Overflow)); | 525 | return Poll::Ready(Err(Error::Overflow)); |
| 530 | } else if r.events_stopped.read().bits() != 0 { | 526 | } else if r.events_stopped().read() != 0 { |
| 531 | r.events_stopped.reset(); | 527 | r.events_stopped().write_value(0); |
| 532 | return match status { | 528 | return match status { |
| 533 | Status::Read => Poll::Ready(Ok(Command::Read)), | 529 | Status::Read => Poll::Ready(Ok(Command::Read)), |
| 534 | Status::Write => { | 530 | Status::Write => { |
| 535 | let n = r.rxd.amount.read().bits() as usize; | 531 | let n = r.rxd().amount().read().0 as usize; |
| 536 | Poll::Ready(Ok(Command::Write(n))) | 532 | Poll::Ready(Ok(Command::Write(n))) |
| 537 | } | 533 | } |
| 538 | }; | 534 | }; |
| 539 | } else if r.events_read.read().bits() != 0 { | 535 | } else if r.events_read().read() != 0 { |
| 540 | r.events_read.reset(); | 536 | r.events_read().write_value(0); |
| 541 | let n = r.rxd.amount.read().bits() as usize; | 537 | let n = r.rxd().amount().read().0 as usize; |
| 542 | return Poll::Ready(Ok(Command::WriteRead(n))); | 538 | return Poll::Ready(Ok(Command::WriteRead(n))); |
| 543 | } | 539 | } |
| 544 | Poll::Pending | 540 | Poll::Pending |
| @@ -554,19 +550,25 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 554 | unsafe { self.set_tx_buffer(buffer)? }; | 550 | unsafe { self.set_tx_buffer(buffer)? }; |
| 555 | 551 | ||
| 556 | // Clear events | 552 | // Clear events |
| 557 | r.events_stopped.reset(); | 553 | r.events_stopped().write_value(0); |
| 558 | r.events_error.reset(); | 554 | r.events_error().write_value(0); |
| 559 | self.clear_errorsrc(); | 555 | self.clear_errorsrc(); |
| 560 | 556 | ||
| 561 | if inten { | 557 | if inten { |
| 562 | r.intenset.write(|w| w.stopped().set().error().set()); | 558 | r.intenset().write(|w| { |
| 559 | w.set_stopped(true); | ||
| 560 | w.set_error(true); | ||
| 561 | }); | ||
| 563 | } else { | 562 | } else { |
| 564 | r.intenclr.write(|w| w.stopped().clear().error().clear()); | 563 | r.intenclr().write(|w| { |
| 564 | w.set_stopped(true); | ||
| 565 | w.set_error(true); | ||
| 566 | }); | ||
| 565 | } | 567 | } |
| 566 | 568 | ||
| 567 | // Start write operation. | 569 | // Start write operation. |
| 568 | r.tasks_preparetx.write(|w| unsafe { w.bits(1) }); | 570 | r.tasks_preparetx().write_value(1); |
| 569 | r.tasks_resume.write(|w| unsafe { w.bits(1) }); | 571 | r.tasks_resume().write_value(1); |
| 570 | Ok(()) | 572 | Ok(()) |
| 571 | } | 573 | } |
| 572 | 574 | ||
| @@ -591,22 +593,30 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 591 | unsafe { self.set_rx_buffer(buffer)? }; | 593 | unsafe { self.set_rx_buffer(buffer)? }; |
| 592 | 594 | ||
| 593 | // Clear events | 595 | // Clear events |
| 594 | r.events_read.reset(); | 596 | r.events_read().write_value(0); |
| 595 | r.events_write.reset(); | 597 | r.events_write().write_value(0); |
| 596 | r.events_stopped.reset(); | 598 | r.events_stopped().write_value(0); |
| 597 | r.events_error.reset(); | 599 | r.events_error().write_value(0); |
| 598 | self.clear_errorsrc(); | 600 | self.clear_errorsrc(); |
| 599 | 601 | ||
| 600 | if inten { | 602 | if inten { |
| 601 | r.intenset | 603 | r.intenset().write(|w| { |
| 602 | .write(|w| w.stopped().set().error().set().read().set().write().set()); | 604 | w.set_stopped(true); |
| 605 | w.set_error(true); | ||
| 606 | w.set_read(true); | ||
| 607 | w.set_write(true); | ||
| 608 | }); | ||
| 603 | } else { | 609 | } else { |
| 604 | r.intenclr | 610 | r.intenclr().write(|w| { |
| 605 | .write(|w| w.stopped().clear().error().clear().read().clear().write().clear()); | 611 | w.set_stopped(true); |
| 612 | w.set_error(true); | ||
| 613 | w.set_read(true); | ||
| 614 | w.set_write(true); | ||
| 615 | }); | ||
| 606 | } | 616 | } |
| 607 | 617 | ||
| 608 | // Start read operation. | 618 | // Start read operation. |
| 609 | r.tasks_preparerx.write(|w| unsafe { w.bits(1) }); | 619 | r.tasks_preparerx().write_value(1); |
| 610 | 620 | ||
| 611 | Ok(()) | 621 | Ok(()) |
| 612 | } | 622 | } |
| @@ -616,16 +626,24 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 616 | compiler_fence(SeqCst); | 626 | compiler_fence(SeqCst); |
| 617 | 627 | ||
| 618 | // Clear events | 628 | // Clear events |
| 619 | r.events_read.reset(); | 629 | r.events_read().write_value(0); |
| 620 | r.events_write.reset(); | 630 | r.events_write().write_value(0); |
| 621 | r.events_stopped.reset(); | 631 | r.events_stopped().write_value(0); |
| 622 | r.events_error.reset(); | 632 | r.events_error().write_value(0); |
| 623 | self.clear_errorsrc(); | 633 | self.clear_errorsrc(); |
| 624 | 634 | ||
| 625 | if inten { | 635 | if inten { |
| 626 | r.intenset.write(|w| w.stopped().set().error().set().read().set()); | 636 | r.intenset().write(|w| { |
| 637 | w.set_stopped(true); | ||
| 638 | w.set_error(true); | ||
| 639 | w.set_read(true); | ||
| 640 | }); | ||
| 627 | } else { | 641 | } else { |
| 628 | r.intenclr.write(|w| w.stopped().clear().error().clear().read().clear()); | 642 | r.intenclr().write(|w| { |
| 643 | w.set_stopped(true); | ||
| 644 | w.set_error(true); | ||
| 645 | w.set_read(true); | ||
| 646 | }); | ||
| 629 | } | 647 | } |
| 630 | 648 | ||
| 631 | Ok(()) | 649 | Ok(()) |
| @@ -745,10 +763,10 @@ impl<'a, T: Instance> Drop for Twis<'a, T> { | |||
| 745 | 763 | ||
| 746 | // disable! | 764 | // disable! |
| 747 | let r = T::regs(); | 765 | let r = T::regs(); |
| 748 | r.enable.write(|w| w.enable().disabled()); | 766 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 749 | 767 | ||
| 750 | gpio::deconfigure_pin(r.psel.sda.read().bits()); | 768 | gpio::deconfigure_pin(r.psel().sda().read()); |
| 751 | gpio::deconfigure_pin(r.psel.scl.read().bits()); | 769 | gpio::deconfigure_pin(r.psel().scl().read()); |
| 752 | 770 | ||
| 753 | trace!("twis drop: done"); | 771 | trace!("twis drop: done"); |
| 754 | } | 772 | } |
| @@ -767,7 +785,7 @@ impl State { | |||
| 767 | } | 785 | } |
| 768 | 786 | ||
| 769 | pub(crate) trait SealedInstance { | 787 | pub(crate) trait SealedInstance { |
| 770 | fn regs() -> &'static pac::twis0::RegisterBlock; | 788 | fn regs() -> pac::twis::Twis; |
| 771 | fn state() -> &'static State; | 789 | fn state() -> &'static State; |
| 772 | } | 790 | } |
| 773 | 791 | ||
| @@ -781,8 +799,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static { | |||
| 781 | macro_rules! impl_twis { | 799 | macro_rules! impl_twis { |
| 782 | ($type:ident, $pac_type:ident, $irq:ident) => { | 800 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 783 | impl crate::twis::SealedInstance for peripherals::$type { | 801 | impl crate::twis::SealedInstance for peripherals::$type { |
| 784 | fn regs() -> &'static pac::twis0::RegisterBlock { | 802 | fn regs() -> pac::twis::Twis { |
| 785 | unsafe { &*pac::$pac_type::ptr() } | 803 | pac::$pac_type |
| 786 | } | 804 | } |
| 787 | fn state() -> &'static crate::twis::State { | 805 | fn state() -> &'static crate::twis::State { |
| 788 | static STATE: crate::twis::State = crate::twis::State::new(); | 806 | static STATE: crate::twis::State = crate::twis::State::new(); |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 4cf193617..2a59d029d 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -21,13 +21,14 @@ use core::task::Poll; | |||
| 21 | use embassy_hal_internal::drop::OnDrop; | 21 | use embassy_hal_internal::drop::OnDrop; |
| 22 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 22 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 23 | use embassy_sync::waitqueue::AtomicWaker; | 23 | use embassy_sync::waitqueue::AtomicWaker; |
| 24 | use pac::uarte0::RegisterBlock; | ||
| 25 | // Re-export SVD variants to allow user to directly set values. | 24 | // Re-export SVD variants to allow user to directly set values. |
| 26 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 25 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; |
| 27 | 26 | ||
| 28 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 27 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 29 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits, SealedPin as _}; | 28 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; |
| 30 | use crate::interrupt::typelevel::Interrupt; | 29 | use crate::interrupt::typelevel::Interrupt; |
| 30 | use crate::pac::gpio::vals as gpiovals; | ||
| 31 | use crate::pac::uarte::vals; | ||
| 31 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; | 32 | use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; |
| 32 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; | 33 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; |
| 33 | use crate::util::slice_in_ram_or; | 34 | use crate::util::slice_in_ram_or; |
| @@ -54,7 +55,7 @@ impl Default for Config { | |||
| 54 | 55 | ||
| 55 | bitflags::bitflags! { | 56 | bitflags::bitflags! { |
| 56 | /// Error source flags | 57 | /// Error source flags |
| 57 | pub struct ErrorSource: u32 { | 58 | pub(crate) struct ErrorSource: u32 { |
| 58 | /// Buffer overrun | 59 | /// Buffer overrun |
| 59 | const OVERRUN = 0x01; | 60 | const OVERRUN = 0x01; |
| 60 | /// Parity error | 61 | /// Parity error |
| @@ -112,20 +113,20 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 112 | let r = T::regs(); | 113 | let r = T::regs(); |
| 113 | let s = T::state(); | 114 | let s = T::state(); |
| 114 | 115 | ||
| 115 | let endrx = r.events_endrx.read().bits(); | 116 | let endrx = r.events_endrx().read(); |
| 116 | let error = r.events_error.read().bits(); | 117 | let error = r.events_error().read(); |
| 117 | if endrx != 0 || error != 0 { | 118 | if endrx != 0 || error != 0 { |
| 118 | s.rx_waker.wake(); | 119 | s.rx_waker.wake(); |
| 119 | if endrx != 0 { | 120 | if endrx != 0 { |
| 120 | r.intenclr.write(|w| w.endrx().clear()); | 121 | r.intenclr().write(|w| w.set_endrx(true)); |
| 121 | } | 122 | } |
| 122 | if error != 0 { | 123 | if error != 0 { |
| 123 | r.intenclr.write(|w| w.error().clear()); | 124 | r.intenclr().write(|w| w.set_error(true)); |
| 124 | } | 125 | } |
| 125 | } | 126 | } |
| 126 | if r.events_endtx.read().bits() != 0 { | 127 | if r.events_endtx().read() != 0 { |
| 127 | s.tx_waker.wake(); | 128 | s.tx_waker.wake(); |
| 128 | r.intenclr.write(|w| w.endtx().clear()); | 129 | r.intenclr().write(|w| w.set_endtx(true)); |
| 129 | } | 130 | } |
| 130 | } | 131 | } |
| 131 | } | 132 | } |
| @@ -200,28 +201,12 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 200 | _ => panic!("RTS and CTS pins must be either both set or none set."), | 201 | _ => panic!("RTS and CTS pins must be either both set or none set."), |
| 201 | }; | 202 | }; |
| 202 | configure(r, config, hardware_flow_control); | 203 | configure(r, config, hardware_flow_control); |
| 203 | 204 | configure_rx_pins(r, rxd, rts); | |
| 204 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); | 205 | configure_tx_pins(r, txd, cts); |
| 205 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | ||
| 206 | |||
| 207 | txd.set_high(); | ||
| 208 | txd.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 209 | r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); | ||
| 210 | |||
| 211 | if let Some(pin) = &cts { | ||
| 212 | pin.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 213 | } | ||
| 214 | r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); | ||
| 215 | |||
| 216 | if let Some(pin) = &rts { | ||
| 217 | pin.set_high(); | ||
| 218 | pin.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 219 | } | ||
| 220 | r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); | ||
| 221 | 206 | ||
| 222 | T::Interrupt::unpend(); | 207 | T::Interrupt::unpend(); |
| 223 | unsafe { T::Interrupt::enable() }; | 208 | unsafe { T::Interrupt::enable() }; |
| 224 | r.enable.write(|w| w.enable().enabled()); | 209 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 225 | 210 | ||
| 226 | let s = T::state(); | 211 | let s = T::state(); |
| 227 | s.tx_rx_refcount.store(2, Ordering::Relaxed); | 212 | s.tx_rx_refcount.store(2, Ordering::Relaxed); |
| @@ -264,7 +249,7 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 264 | /// Return the endtx event for use with PPI | 249 | /// Return the endtx event for use with PPI |
| 265 | pub fn event_endtx(&self) -> Event { | 250 | pub fn event_endtx(&self) -> Event { |
| 266 | let r = T::regs(); | 251 | let r = T::regs(); |
| 267 | Event::from_reg(&r.events_endtx) | 252 | Event::from_reg(r.events_endtx()) |
| 268 | } | 253 | } |
| 269 | 254 | ||
| 270 | /// Read bytes until the buffer is filled. | 255 | /// Read bytes until the buffer is filled. |
| @@ -298,27 +283,72 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 298 | } | 283 | } |
| 299 | } | 284 | } |
| 300 | 285 | ||
| 301 | pub(crate) fn configure(r: &RegisterBlock, config: Config, hardware_flow_control: bool) { | 286 | pub(crate) fn configure_tx_pins( |
| 302 | r.config.write(|w| { | 287 | r: pac::uarte::Uarte, |
| 303 | w.hwfc().bit(hardware_flow_control); | 288 | txd: PeripheralRef<'_, AnyPin>, |
| 304 | w.parity().variant(config.parity); | 289 | cts: Option<PeripheralRef<'_, AnyPin>>, |
| 305 | w | 290 | ) { |
| 291 | txd.set_high(); | ||
| 292 | txd.conf().write(|w| { | ||
| 293 | w.set_dir(gpiovals::Dir::OUTPUT); | ||
| 294 | w.set_input(gpiovals::Input::DISCONNECT); | ||
| 295 | w.set_drive(gpiovals::Drive::H0H1); | ||
| 306 | }); | 296 | }); |
| 307 | r.baudrate.write(|w| w.baudrate().variant(config.baudrate)); | 297 | r.psel().txd().write_value(txd.psel_bits()); |
| 298 | |||
| 299 | if let Some(pin) = &cts { | ||
| 300 | pin.conf().write(|w| { | ||
| 301 | w.set_dir(gpiovals::Dir::INPUT); | ||
| 302 | w.set_input(gpiovals::Input::CONNECT); | ||
| 303 | w.set_drive(gpiovals::Drive::H0H1); | ||
| 304 | }); | ||
| 305 | } | ||
| 306 | r.psel().cts().write_value(cts.psel_bits()); | ||
| 307 | } | ||
| 308 | |||
| 309 | pub(crate) fn configure_rx_pins( | ||
| 310 | r: pac::uarte::Uarte, | ||
| 311 | rxd: PeripheralRef<'_, AnyPin>, | ||
| 312 | rts: Option<PeripheralRef<'_, AnyPin>>, | ||
| 313 | ) { | ||
| 314 | rxd.conf().write(|w| { | ||
| 315 | w.set_dir(gpiovals::Dir::INPUT); | ||
| 316 | w.set_input(gpiovals::Input::CONNECT); | ||
| 317 | w.set_drive(gpiovals::Drive::H0H1); | ||
| 318 | }); | ||
| 319 | r.psel().rxd().write_value(rxd.psel_bits()); | ||
| 320 | |||
| 321 | if let Some(pin) = &rts { | ||
| 322 | pin.set_high(); | ||
| 323 | pin.conf().write(|w| { | ||
| 324 | w.set_dir(gpiovals::Dir::OUTPUT); | ||
| 325 | w.set_input(gpiovals::Input::DISCONNECT); | ||
| 326 | w.set_drive(gpiovals::Drive::H0H1); | ||
| 327 | }); | ||
| 328 | } | ||
| 329 | r.psel().rts().write_value(rts.psel_bits()); | ||
| 330 | } | ||
| 331 | |||
| 332 | pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_control: bool) { | ||
| 333 | r.config().write(|w| { | ||
| 334 | w.set_hwfc(hardware_flow_control); | ||
| 335 | w.set_parity(config.parity); | ||
| 336 | }); | ||
| 337 | r.baudrate().write(|w| w.set_baudrate(config.baudrate)); | ||
| 308 | 338 | ||
| 309 | // Disable all interrupts | 339 | // Disable all interrupts |
| 310 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 340 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| 311 | 341 | ||
| 312 | // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was | 342 | // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was |
| 313 | // stopped midway or not. | 343 | // stopped midway or not. |
| 314 | r.events_rxstarted.reset(); | 344 | r.events_rxstarted().write_value(0); |
| 315 | r.events_txstarted.reset(); | 345 | r.events_txstarted().write_value(0); |
| 316 | 346 | ||
| 317 | // reset all pins | 347 | // reset all pins |
| 318 | r.psel.txd.write(|w| w.connect().disconnected()); | 348 | r.psel().txd().write_value(DISCONNECTED); |
| 319 | r.psel.rxd.write(|w| w.connect().disconnected()); | 349 | r.psel().rxd().write_value(DISCONNECTED); |
| 320 | r.psel.cts.write(|w| w.connect().disconnected()); | 350 | r.psel().cts().write_value(DISCONNECTED); |
| 321 | r.psel.rts.write(|w| w.connect().disconnected()); | 351 | r.psel().rts().write_value(DISCONNECTED); |
| 322 | 352 | ||
| 323 | apply_workaround_for_enable_anomaly(r); | 353 | apply_workaround_for_enable_anomaly(r); |
| 324 | } | 354 | } |
| @@ -356,19 +386,11 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 356 | let r = T::regs(); | 386 | let r = T::regs(); |
| 357 | 387 | ||
| 358 | configure(r, config, cts.is_some()); | 388 | configure(r, config, cts.is_some()); |
| 359 | 389 | configure_tx_pins(r, txd, cts); | |
| 360 | txd.set_high(); | ||
| 361 | txd.conf().write(|w| w.dir().output().drive().s0s1()); | ||
| 362 | r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); | ||
| 363 | |||
| 364 | if let Some(pin) = &cts { | ||
| 365 | pin.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 366 | } | ||
| 367 | r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); | ||
| 368 | 390 | ||
| 369 | T::Interrupt::unpend(); | 391 | T::Interrupt::unpend(); |
| 370 | unsafe { T::Interrupt::enable() }; | 392 | unsafe { T::Interrupt::enable() }; |
| 371 | r.enable.write(|w| w.enable().enabled()); | 393 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 372 | 394 | ||
| 373 | let s = T::state(); | 395 | let s = T::state(); |
| 374 | s.tx_rx_refcount.store(1, Ordering::Relaxed); | 396 | s.tx_rx_refcount.store(1, Ordering::Relaxed); |
| @@ -410,29 +432,29 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 410 | let drop = OnDrop::new(move || { | 432 | let drop = OnDrop::new(move || { |
| 411 | trace!("write drop: stopping"); | 433 | trace!("write drop: stopping"); |
| 412 | 434 | ||
| 413 | r.intenclr.write(|w| w.endtx().clear()); | 435 | r.intenclr().write(|w| w.set_endtx(true)); |
| 414 | r.events_txstopped.reset(); | 436 | r.events_txstopped().write_value(0); |
| 415 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | 437 | r.tasks_stoptx().write_value(1); |
| 416 | 438 | ||
| 417 | // TX is stopped almost instantly, spinning is fine. | 439 | // TX is stopped almost instantly, spinning is fine. |
| 418 | while r.events_endtx.read().bits() == 0 {} | 440 | while r.events_endtx().read() == 0 {} |
| 419 | trace!("write drop: stopped"); | 441 | trace!("write drop: stopped"); |
| 420 | }); | 442 | }); |
| 421 | 443 | ||
| 422 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 444 | r.txd().ptr().write_value(ptr as u32); |
| 423 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 445 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 424 | 446 | ||
| 425 | r.events_endtx.reset(); | 447 | r.events_endtx().write_value(0); |
| 426 | r.intenset.write(|w| w.endtx().set()); | 448 | r.intenset().write(|w| w.set_endtx(true)); |
| 427 | 449 | ||
| 428 | compiler_fence(Ordering::SeqCst); | 450 | compiler_fence(Ordering::SeqCst); |
| 429 | 451 | ||
| 430 | trace!("starttx"); | 452 | trace!("starttx"); |
| 431 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 453 | r.tasks_starttx().write_value(1); |
| 432 | 454 | ||
| 433 | poll_fn(|cx| { | 455 | poll_fn(|cx| { |
| 434 | s.tx_waker.register(cx.waker()); | 456 | s.tx_waker.register(cx.waker()); |
| 435 | if r.events_endtx.read().bits() != 0 { | 457 | if r.events_endtx().read() != 0 { |
| 436 | return Poll::Ready(()); | 458 | return Poll::Ready(()); |
| 437 | } | 459 | } |
| 438 | Poll::Pending | 460 | Poll::Pending |
| @@ -440,7 +462,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 440 | .await; | 462 | .await; |
| 441 | 463 | ||
| 442 | compiler_fence(Ordering::SeqCst); | 464 | compiler_fence(Ordering::SeqCst); |
| 443 | r.events_txstarted.reset(); | 465 | r.events_txstarted().write_value(0); |
| 444 | drop.defuse(); | 466 | drop.defuse(); |
| 445 | 467 | ||
| 446 | Ok(()) | 468 | Ok(()) |
| @@ -476,21 +498,21 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 476 | 498 | ||
| 477 | let r = T::regs(); | 499 | let r = T::regs(); |
| 478 | 500 | ||
| 479 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 501 | r.txd().ptr().write_value(ptr as u32); |
| 480 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 502 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 481 | 503 | ||
| 482 | r.events_endtx.reset(); | 504 | r.events_endtx().write_value(0); |
| 483 | r.intenclr.write(|w| w.endtx().clear()); | 505 | r.intenclr().write(|w| w.set_endtx(true)); |
| 484 | 506 | ||
| 485 | compiler_fence(Ordering::SeqCst); | 507 | compiler_fence(Ordering::SeqCst); |
| 486 | 508 | ||
| 487 | trace!("starttx"); | 509 | trace!("starttx"); |
| 488 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 510 | r.tasks_starttx().write_value(1); |
| 489 | 511 | ||
| 490 | while r.events_endtx.read().bits() == 0 {} | 512 | while r.events_endtx().read() == 0 {} |
| 491 | 513 | ||
| 492 | compiler_fence(Ordering::SeqCst); | 514 | compiler_fence(Ordering::SeqCst); |
| 493 | r.events_txstarted.reset(); | 515 | r.events_txstarted().write_value(0); |
| 494 | 516 | ||
| 495 | Ok(()) | 517 | Ok(()) |
| 496 | } | 518 | } |
| @@ -502,11 +524,11 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> { | |||
| 502 | 524 | ||
| 503 | let r = T::regs(); | 525 | let r = T::regs(); |
| 504 | 526 | ||
| 505 | let did_stoptx = r.events_txstarted.read().bits() != 0; | 527 | let did_stoptx = r.events_txstarted().read() != 0; |
| 506 | trace!("did_stoptx {}", did_stoptx); | 528 | trace!("did_stoptx {}", did_stoptx); |
| 507 | 529 | ||
| 508 | // Wait for txstopped, if needed. | 530 | // Wait for txstopped, if needed. |
| 509 | while did_stoptx && r.events_txstopped.read().bits() == 0 {} | 531 | while did_stoptx && r.events_txstopped().read() == 0 {} |
| 510 | 532 | ||
| 511 | let s = T::state(); | 533 | let s = T::state(); |
| 512 | 534 | ||
| @@ -541,9 +563,9 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 541 | /// Check for errors and clear the error register if an error occured. | 563 | /// Check for errors and clear the error register if an error occured. |
| 542 | fn check_and_clear_errors(&mut self) -> Result<(), Error> { | 564 | fn check_and_clear_errors(&mut self) -> Result<(), Error> { |
| 543 | let r = T::regs(); | 565 | let r = T::regs(); |
| 544 | let err_bits = r.errorsrc.read().bits(); | 566 | let err_bits = r.errorsrc().read(); |
| 545 | r.errorsrc.write(|w| unsafe { w.bits(err_bits) }); | 567 | r.errorsrc().write_value(err_bits); |
| 546 | ErrorSource::from_bits_truncate(err_bits).check() | 568 | ErrorSource::from_bits_truncate(err_bits.0).check() |
| 547 | } | 569 | } |
| 548 | 570 | ||
| 549 | fn new_inner( | 571 | fn new_inner( |
| @@ -555,19 +577,11 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 555 | let r = T::regs(); | 577 | let r = T::regs(); |
| 556 | 578 | ||
| 557 | configure(r, config, rts.is_some()); | 579 | configure(r, config, rts.is_some()); |
| 558 | 580 | configure_rx_pins(r, rxd, rts); | |
| 559 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 560 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | ||
| 561 | |||
| 562 | if let Some(pin) = &rts { | ||
| 563 | pin.set_high(); | ||
| 564 | pin.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 565 | } | ||
| 566 | r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); | ||
| 567 | 581 | ||
| 568 | T::Interrupt::unpend(); | 582 | T::Interrupt::unpend(); |
| 569 | unsafe { T::Interrupt::enable() }; | 583 | unsafe { T::Interrupt::enable() }; |
| 570 | r.enable.write(|w| w.enable().enabled()); | 584 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 571 | 585 | ||
| 572 | let s = T::state(); | 586 | let s = T::state(); |
| 573 | s.tx_rx_refcount.store(1, Ordering::Relaxed); | 587 | s.tx_rx_refcount.store(1, Ordering::Relaxed); |
| @@ -594,8 +608,8 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 594 | // We want to stop RX if line is idle for 2 bytes worth of time | 608 | // We want to stop RX if line is idle for 2 bytes worth of time |
| 595 | // That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit) | 609 | // That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit) |
| 596 | // This gives us the amount of 16M ticks for 20 bits. | 610 | // This gives us the amount of 16M ticks for 20 bits. |
| 597 | let baudrate = r.baudrate.read().baudrate().variant().unwrap(); | 611 | let baudrate = r.baudrate().read().baudrate(); |
| 598 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); | 612 | let timeout = 0x8000_0000 / (baudrate.to_bits() / 40); |
| 599 | 613 | ||
| 600 | timer.set_frequency(Frequency::F16MHz); | 614 | timer.set_frequency(Frequency::F16MHz); |
| 601 | timer.cc(0).write(timeout); | 615 | timer.cc(0).write(timeout); |
| @@ -604,7 +618,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 604 | 618 | ||
| 605 | let mut ppi_ch1 = Ppi::new_one_to_two( | 619 | let mut ppi_ch1 = Ppi::new_one_to_two( |
| 606 | ppi_ch1.map_into(), | 620 | ppi_ch1.map_into(), |
| 607 | Event::from_reg(&r.events_rxdrdy), | 621 | Event::from_reg(r.events_rxdrdy()), |
| 608 | timer.task_clear(), | 622 | timer.task_clear(), |
| 609 | timer.task_start(), | 623 | timer.task_start(), |
| 610 | ); | 624 | ); |
| @@ -613,7 +627,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 613 | let mut ppi_ch2 = Ppi::new_one_to_one( | 627 | let mut ppi_ch2 = Ppi::new_one_to_one( |
| 614 | ppi_ch2.map_into(), | 628 | ppi_ch2.map_into(), |
| 615 | timer.cc(0).event_compare(), | 629 | timer.cc(0).event_compare(), |
| 616 | Task::from_reg(&r.tasks_stoprx), | 630 | Task::from_reg(r.tasks_stoprx()), |
| 617 | ); | 631 | ); |
| 618 | ppi_ch2.enable(); | 632 | ppi_ch2.enable(); |
| 619 | 633 | ||
| @@ -643,43 +657,42 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 643 | let drop = OnDrop::new(move || { | 657 | let drop = OnDrop::new(move || { |
| 644 | trace!("read drop: stopping"); | 658 | trace!("read drop: stopping"); |
| 645 | 659 | ||
| 646 | r.intenclr.write(|w| { | 660 | r.intenclr().write(|w| { |
| 647 | w.endrx().clear(); | 661 | w.set_endrx(true); |
| 648 | w.error().clear() | 662 | w.set_error(true); |
| 649 | }); | 663 | }); |
| 650 | r.events_rxto.reset(); | 664 | r.events_rxto().write_value(0); |
| 651 | r.events_error.reset(); | 665 | r.events_error().write_value(0); |
| 652 | r.errorsrc.reset(); | 666 | r.tasks_stoprx().write_value(1); |
| 653 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | ||
| 654 | 667 | ||
| 655 | while r.events_endrx.read().bits() == 0 {} | 668 | while r.events_endrx().read() == 0 {} |
| 656 | 669 | ||
| 657 | trace!("read drop: stopped"); | 670 | trace!("read drop: stopped"); |
| 658 | }); | 671 | }); |
| 659 | 672 | ||
| 660 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 673 | r.rxd().ptr().write_value(ptr as u32); |
| 661 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 674 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 662 | 675 | ||
| 663 | r.events_endrx.reset(); | 676 | r.events_endrx().write_value(0); |
| 664 | r.events_error.reset(); | 677 | r.events_error().write_value(0); |
| 665 | r.intenset.write(|w| { | 678 | r.intenset().write(|w| { |
| 666 | w.endrx().set(); | 679 | w.set_endrx(true); |
| 667 | w.error().set() | 680 | w.set_error(true); |
| 668 | }); | 681 | }); |
| 669 | 682 | ||
| 670 | compiler_fence(Ordering::SeqCst); | 683 | compiler_fence(Ordering::SeqCst); |
| 671 | 684 | ||
| 672 | trace!("startrx"); | 685 | trace!("startrx"); |
| 673 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 686 | r.tasks_startrx().write_value(1); |
| 674 | 687 | ||
| 675 | let result = poll_fn(|cx| { | 688 | let result = poll_fn(|cx| { |
| 676 | s.rx_waker.register(cx.waker()); | 689 | s.rx_waker.register(cx.waker()); |
| 677 | 690 | ||
| 678 | if let Err(e) = self.check_and_clear_errors() { | 691 | if let Err(e) = self.check_and_clear_errors() { |
| 679 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | 692 | r.tasks_stoprx().write_value(1); |
| 680 | return Poll::Ready(Err(e)); | 693 | return Poll::Ready(Err(e)); |
| 681 | } | 694 | } |
| 682 | if r.events_endrx.read().bits() != 0 { | 695 | if r.events_endrx().read() != 0 { |
| 683 | return Poll::Ready(Ok(())); | 696 | return Poll::Ready(Ok(())); |
| 684 | } | 697 | } |
| 685 | Poll::Pending | 698 | Poll::Pending |
| @@ -687,7 +700,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 687 | .await; | 700 | .await; |
| 688 | 701 | ||
| 689 | compiler_fence(Ordering::SeqCst); | 702 | compiler_fence(Ordering::SeqCst); |
| 690 | r.events_rxstarted.reset(); | 703 | r.events_rxstarted().write_value(0); |
| 691 | drop.defuse(); | 704 | drop.defuse(); |
| 692 | 705 | ||
| 693 | result | 706 | result |
| @@ -707,25 +720,25 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 707 | 720 | ||
| 708 | let r = T::regs(); | 721 | let r = T::regs(); |
| 709 | 722 | ||
| 710 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 723 | r.rxd().ptr().write_value(ptr as u32); |
| 711 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 724 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 712 | 725 | ||
| 713 | r.events_endrx.reset(); | 726 | r.events_endrx().write_value(0); |
| 714 | r.events_error.reset(); | 727 | r.events_error().write_value(0); |
| 715 | r.intenclr.write(|w| { | 728 | r.intenclr().write(|w| { |
| 716 | w.endrx().clear(); | 729 | w.set_endrx(true); |
| 717 | w.error().clear() | 730 | w.set_error(true); |
| 718 | }); | 731 | }); |
| 719 | 732 | ||
| 720 | compiler_fence(Ordering::SeqCst); | 733 | compiler_fence(Ordering::SeqCst); |
| 721 | 734 | ||
| 722 | trace!("startrx"); | 735 | trace!("startrx"); |
| 723 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 736 | r.tasks_startrx().write_value(1); |
| 724 | 737 | ||
| 725 | while r.events_endrx.read().bits() == 0 && r.events_error.read().bits() == 0 {} | 738 | while r.events_endrx().read() == 0 && r.events_error().read() == 0 {} |
| 726 | 739 | ||
| 727 | compiler_fence(Ordering::SeqCst); | 740 | compiler_fence(Ordering::SeqCst); |
| 728 | r.events_rxstarted.reset(); | 741 | r.events_rxstarted().write_value(0); |
| 729 | 742 | ||
| 730 | self.check_and_clear_errors() | 743 | self.check_and_clear_errors() |
| 731 | } | 744 | } |
| @@ -737,11 +750,11 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> { | |||
| 737 | 750 | ||
| 738 | let r = T::regs(); | 751 | let r = T::regs(); |
| 739 | 752 | ||
| 740 | let did_stoprx = r.events_rxstarted.read().bits() != 0; | 753 | let did_stoprx = r.events_rxstarted().read() != 0; |
| 741 | trace!("did_stoprx {}", did_stoprx); | 754 | trace!("did_stoprx {}", did_stoprx); |
| 742 | 755 | ||
| 743 | // Wait for rxto, if needed. | 756 | // Wait for rxto, if needed. |
| 744 | while did_stoprx && r.events_rxto.read().bits() == 0 {} | 757 | while did_stoprx && r.events_rxto().read() == 0 {} |
| 745 | 758 | ||
| 746 | let s = T::state(); | 759 | let s = T::state(); |
| 747 | 760 | ||
| @@ -794,39 +807,39 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | |||
| 794 | let drop = OnDrop::new(|| { | 807 | let drop = OnDrop::new(|| { |
| 795 | self.timer.stop(); | 808 | self.timer.stop(); |
| 796 | 809 | ||
| 797 | r.intenclr.write(|w| { | 810 | r.intenclr().write(|w| { |
| 798 | w.endrx().clear(); | 811 | w.set_endrx(true); |
| 799 | w.error().clear() | 812 | w.set_error(true); |
| 800 | }); | 813 | }); |
| 801 | r.events_rxto.reset(); | 814 | r.events_rxto().write_value(0); |
| 802 | r.events_error.reset(); | 815 | r.events_error().write_value(0); |
| 803 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | 816 | r.tasks_stoprx().write_value(1); |
| 804 | 817 | ||
| 805 | while r.events_endrx.read().bits() == 0 {} | 818 | while r.events_endrx().read() == 0 {} |
| 806 | }); | 819 | }); |
| 807 | 820 | ||
| 808 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 821 | r.rxd().ptr().write_value(ptr as u32); |
| 809 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 822 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 810 | 823 | ||
| 811 | r.events_endrx.reset(); | 824 | r.events_endrx().write_value(0); |
| 812 | r.events_error.reset(); | 825 | r.events_error().write_value(0); |
| 813 | r.intenset.write(|w| { | 826 | r.intenset().write(|w| { |
| 814 | w.endrx().set(); | 827 | w.set_endrx(true); |
| 815 | w.error().set() | 828 | w.set_error(true); |
| 816 | }); | 829 | }); |
| 817 | 830 | ||
| 818 | compiler_fence(Ordering::SeqCst); | 831 | compiler_fence(Ordering::SeqCst); |
| 819 | 832 | ||
| 820 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 833 | r.tasks_startrx().write_value(1); |
| 821 | 834 | ||
| 822 | let result = poll_fn(|cx| { | 835 | let result = poll_fn(|cx| { |
| 823 | s.rx_waker.register(cx.waker()); | 836 | s.rx_waker.register(cx.waker()); |
| 824 | 837 | ||
| 825 | if let Err(e) = self.rx.check_and_clear_errors() { | 838 | if let Err(e) = self.rx.check_and_clear_errors() { |
| 826 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | 839 | r.tasks_stoprx().write_value(1); |
| 827 | return Poll::Ready(Err(e)); | 840 | return Poll::Ready(Err(e)); |
| 828 | } | 841 | } |
| 829 | if r.events_endrx.read().bits() != 0 { | 842 | if r.events_endrx().read() != 0 { |
| 830 | return Poll::Ready(Ok(())); | 843 | return Poll::Ready(Ok(())); |
| 831 | } | 844 | } |
| 832 | 845 | ||
| @@ -835,10 +848,10 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | |||
| 835 | .await; | 848 | .await; |
| 836 | 849 | ||
| 837 | compiler_fence(Ordering::SeqCst); | 850 | compiler_fence(Ordering::SeqCst); |
| 838 | let n = r.rxd.amount.read().amount().bits() as usize; | 851 | let n = r.rxd().amount().read().0 as usize; |
| 839 | 852 | ||
| 840 | self.timer.stop(); | 853 | self.timer.stop(); |
| 841 | r.events_rxstarted.reset(); | 854 | r.events_rxstarted().write_value(0); |
| 842 | 855 | ||
| 843 | drop.defuse(); | 856 | drop.defuse(); |
| 844 | 857 | ||
| @@ -863,56 +876,57 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | |||
| 863 | 876 | ||
| 864 | self.ppi_ch1.enable(); | 877 | self.ppi_ch1.enable(); |
| 865 | 878 | ||
| 866 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 879 | r.rxd().ptr().write_value(ptr as u32); |
| 867 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 880 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 868 | 881 | ||
| 869 | r.events_endrx.reset(); | 882 | r.events_endrx().write_value(0); |
| 870 | r.events_error.reset(); | 883 | r.events_error().write_value(0); |
| 871 | r.intenclr.write(|w| { | 884 | r.intenclr().write(|w| { |
| 872 | w.endrx().clear(); | 885 | w.set_endrx(true); |
| 873 | w.error().clear() | 886 | w.set_error(true); |
| 874 | }); | 887 | }); |
| 875 | 888 | ||
| 876 | compiler_fence(Ordering::SeqCst); | 889 | compiler_fence(Ordering::SeqCst); |
| 877 | 890 | ||
| 878 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 891 | r.tasks_startrx().write_value(1); |
| 879 | 892 | ||
| 880 | while r.events_endrx.read().bits() == 0 && r.events_error.read().bits() == 0 {} | 893 | while r.events_endrx().read() == 0 && r.events_error().read() == 0 {} |
| 881 | 894 | ||
| 882 | compiler_fence(Ordering::SeqCst); | 895 | compiler_fence(Ordering::SeqCst); |
| 883 | let n = r.rxd.amount.read().amount().bits() as usize; | 896 | let n = r.rxd().amount().read().0 as usize; |
| 884 | 897 | ||
| 885 | self.timer.stop(); | 898 | self.timer.stop(); |
| 886 | r.events_rxstarted.reset(); | 899 | r.events_rxstarted().write_value(0); |
| 887 | 900 | ||
| 888 | self.rx.check_and_clear_errors().map(|_| n) | 901 | self.rx.check_and_clear_errors().map(|_| n) |
| 889 | } | 902 | } |
| 890 | } | 903 | } |
| 891 | 904 | ||
| 892 | #[cfg(not(any(feature = "_nrf9160", feature = "_nrf5340")))] | 905 | #[cfg(not(any(feature = "_nrf9160", feature = "_nrf5340")))] |
| 893 | pub(crate) fn apply_workaround_for_enable_anomaly(_r: &crate::pac::uarte0::RegisterBlock) { | 906 | pub(crate) fn apply_workaround_for_enable_anomaly(_r: pac::uarte::Uarte) { |
| 894 | // Do nothing | 907 | // Do nothing |
| 895 | } | 908 | } |
| 896 | 909 | ||
| 897 | #[cfg(any(feature = "_nrf9160", feature = "_nrf5340"))] | 910 | #[cfg(any(feature = "_nrf9160", feature = "_nrf5340"))] |
| 898 | pub(crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::RegisterBlock) { | 911 | pub(crate) fn apply_workaround_for_enable_anomaly(r: pac::uarte::Uarte) { |
| 899 | // Apply workaround for anomalies: | 912 | // Apply workaround for anomalies: |
| 900 | // - nRF9160 - anomaly 23 | 913 | // - nRF9160 - anomaly 23 |
| 901 | // - nRF5340 - anomaly 44 | 914 | // - nRF5340 - anomaly 44 |
| 902 | let rxenable_reg: *const u32 = ((r as *const _ as usize) + 0x564) as *const u32; | 915 | let rp = r.as_ptr() as *mut u32; |
| 903 | let txenable_reg: *const u32 = ((r as *const _ as usize) + 0x568) as *const u32; | 916 | let rxenable_reg = unsafe { rp.add(0x564 / 4) }; |
| 917 | let txenable_reg = unsafe { rp.add(0x568 / 4) }; | ||
| 904 | 918 | ||
| 905 | // NB Safety: This is taken from Nordic's driver - | 919 | // NB Safety: This is taken from Nordic's driver - |
| 906 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | 920 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 |
| 907 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { | 921 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { |
| 908 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | 922 | r.tasks_stoptx().write_value(1); |
| 909 | } | 923 | } |
| 910 | 924 | ||
| 911 | // NB Safety: This is taken from Nordic's driver - | 925 | // NB Safety: This is taken from Nordic's driver - |
| 912 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | 926 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 |
| 913 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { | 927 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { |
| 914 | r.enable.write(|w| w.enable().enabled()); | 928 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 915 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | 929 | r.tasks_stoprx().write_value(1); |
| 916 | 930 | ||
| 917 | let mut workaround_succeded = false; | 931 | let mut workaround_succeded = false; |
| 918 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. | 932 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. |
| @@ -933,23 +947,23 @@ pub(crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::Regist | |||
| 933 | panic!("Failed to apply workaround for UART"); | 947 | panic!("Failed to apply workaround for UART"); |
| 934 | } | 948 | } |
| 935 | 949 | ||
| 936 | let errors = r.errorsrc.read().bits(); | 950 | // write back the bits we just read to clear them |
| 937 | // NB Safety: safe to write back the bits we just read to clear them | 951 | let errors = r.errorsrc().read(); |
| 938 | r.errorsrc.write(|w| unsafe { w.bits(errors) }); | 952 | r.errorsrc().write_value(errors); |
| 939 | r.enable.write(|w| w.enable().disabled()); | 953 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 940 | } | 954 | } |
| 941 | } | 955 | } |
| 942 | 956 | ||
| 943 | pub(crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &State) { | 957 | pub(crate) fn drop_tx_rx(r: pac::uarte::Uarte, s: &State) { |
| 944 | if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 { | 958 | if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 { |
| 945 | // Finally we can disable, and we do so for the peripheral | 959 | // Finally we can disable, and we do so for the peripheral |
| 946 | // i.e. not just rx concerns. | 960 | // i.e. not just rx concerns. |
| 947 | r.enable.write(|w| w.enable().disabled()); | 961 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 948 | 962 | ||
| 949 | gpio::deconfigure_pin(r.psel.rxd.read().bits()); | 963 | gpio::deconfigure_pin(r.psel().rxd().read()); |
| 950 | gpio::deconfigure_pin(r.psel.txd.read().bits()); | 964 | gpio::deconfigure_pin(r.psel().txd().read()); |
| 951 | gpio::deconfigure_pin(r.psel.rts.read().bits()); | 965 | gpio::deconfigure_pin(r.psel().rts().read()); |
| 952 | gpio::deconfigure_pin(r.psel.cts.read().bits()); | 966 | gpio::deconfigure_pin(r.psel().cts().read()); |
| 953 | 967 | ||
| 954 | trace!("uarte tx and rx drop: done"); | 968 | trace!("uarte tx and rx drop: done"); |
| 955 | } | 969 | } |
| @@ -971,7 +985,7 @@ impl State { | |||
| 971 | } | 985 | } |
| 972 | 986 | ||
| 973 | pub(crate) trait SealedInstance { | 987 | pub(crate) trait SealedInstance { |
| 974 | fn regs() -> &'static pac::uarte0::RegisterBlock; | 988 | fn regs() -> pac::uarte::Uarte; |
| 975 | fn state() -> &'static State; | 989 | fn state() -> &'static State; |
| 976 | fn buffered_state() -> &'static crate::buffered_uarte::State; | 990 | fn buffered_state() -> &'static crate::buffered_uarte::State; |
| 977 | } | 991 | } |
| @@ -986,8 +1000,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 986 | macro_rules! impl_uarte { | 1000 | macro_rules! impl_uarte { |
| 987 | ($type:ident, $pac_type:ident, $irq:ident) => { | 1001 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 988 | impl crate::uarte::SealedInstance for peripherals::$type { | 1002 | impl crate::uarte::SealedInstance for peripherals::$type { |
| 989 | fn regs() -> &'static pac::uarte0::RegisterBlock { | 1003 | fn regs() -> pac::uarte::Uarte { |
| 990 | unsafe { &*pac::$pac_type::ptr() } | 1004 | pac::$pac_type |
| 991 | } | 1005 | } |
| 992 | fn state() -> &'static crate::uarte::State { | 1006 | fn state() -> &'static crate::uarte::State { |
| 993 | static STATE: crate::uarte::State = crate::uarte::State::new(); | 1007 | static STATE: crate::uarte::State = crate::uarte::State::new(); |
diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs index 8cbb1a350..52c9c532b 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs | |||
| @@ -15,10 +15,10 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 15 | use embassy_sync::waitqueue::AtomicWaker; | 15 | use embassy_sync::waitqueue::AtomicWaker; |
| 16 | use embassy_usb_driver as driver; | 16 | use embassy_usb_driver as driver; |
| 17 | use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; | 17 | use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo, EndpointType, Event, Unsupported}; |
| 18 | use pac::usbd::RegisterBlock; | ||
| 19 | 18 | ||
| 20 | use self::vbus_detect::VbusDetect; | 19 | use self::vbus_detect::VbusDetect; |
| 21 | use crate::interrupt::typelevel::Interrupt; | 20 | use crate::interrupt::typelevel::Interrupt; |
| 21 | use crate::pac::usbd::vals; | ||
| 22 | use crate::util::slice_in_ram; | 22 | use crate::util::slice_in_ram; |
| 23 | use crate::{interrupt, pac, Peripheral}; | 23 | use crate::{interrupt, pac, Peripheral}; |
| 24 | 24 | ||
| @@ -38,19 +38,19 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 38 | unsafe fn on_interrupt() { | 38 | unsafe fn on_interrupt() { |
| 39 | let regs = T::regs(); | 39 | let regs = T::regs(); |
| 40 | 40 | ||
| 41 | if regs.events_usbreset.read().bits() != 0 { | 41 | if regs.events_usbreset().read() != 0 { |
| 42 | regs.intenclr.write(|w| w.usbreset().clear()); | 42 | regs.intenclr().write(|w| w.set_usbreset(true)); |
| 43 | BUS_WAKER.wake(); | 43 | BUS_WAKER.wake(); |
| 44 | EP0_WAKER.wake(); | 44 | EP0_WAKER.wake(); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | if regs.events_ep0setup.read().bits() != 0 { | 47 | if regs.events_ep0setup().read() != 0 { |
| 48 | regs.intenclr.write(|w| w.ep0setup().clear()); | 48 | regs.intenclr().write(|w| w.set_ep0setup(true)); |
| 49 | EP0_WAKER.wake(); | 49 | EP0_WAKER.wake(); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | if regs.events_ep0datadone.read().bits() != 0 { | 52 | if regs.events_ep0datadone().read() != 0 { |
| 53 | regs.intenclr.write(|w| w.ep0datadone().clear()); | 53 | regs.intenclr().write(|w| w.set_ep0datadone(true)); |
| 54 | EP0_WAKER.wake(); | 54 | EP0_WAKER.wake(); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| @@ -63,22 +63,22 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 63 | // Therefore, it's fine to clear just the event, and let main thread | 63 | // Therefore, it's fine to clear just the event, and let main thread |
| 64 | // check the individual bits in EVENTCAUSE and EPDATASTATUS. It | 64 | // check the individual bits in EVENTCAUSE and EPDATASTATUS. It |
| 65 | // doesn't cause an infinite irq loop. | 65 | // doesn't cause an infinite irq loop. |
| 66 | if regs.events_usbevent.read().bits() != 0 { | 66 | if regs.events_usbevent().read() != 0 { |
| 67 | regs.events_usbevent.reset(); | 67 | regs.events_usbevent().write_value(0); |
| 68 | BUS_WAKER.wake(); | 68 | BUS_WAKER.wake(); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | if regs.events_epdata.read().bits() != 0 { | 71 | if regs.events_epdata().read() != 0 { |
| 72 | regs.events_epdata.reset(); | 72 | regs.events_epdata().write_value(0); |
| 73 | 73 | ||
| 74 | let r = regs.epdatastatus.read().bits(); | 74 | let r = regs.epdatastatus().read(); |
| 75 | regs.epdatastatus.write(|w| unsafe { w.bits(r) }); | 75 | regs.epdatastatus().write_value(r); |
| 76 | READY_ENDPOINTS.fetch_or(r, Ordering::AcqRel); | 76 | READY_ENDPOINTS.fetch_or(r.0, Ordering::AcqRel); |
| 77 | for i in 1..=7 { | 77 | for i in 1..=7 { |
| 78 | if r & In::mask(i) != 0 { | 78 | if r.0 & In::mask(i) != 0 { |
| 79 | In::waker(i).wake(); | 79 | In::waker(i).wake(); |
| 80 | } | 80 | } |
| 81 | if r & Out::mask(i) != 0 { | 81 | if r.0 & Out::mask(i) != 0 { |
| 82 | Out::waker(i).wake(); | 82 | Out::waker(i).wake(); |
| 83 | } | 83 | } |
| 84 | } | 84 | } |
| @@ -181,35 +181,34 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 181 | 181 | ||
| 182 | errata::pre_enable(); | 182 | errata::pre_enable(); |
| 183 | 183 | ||
| 184 | regs.enable.write(|w| w.enable().enabled()); | 184 | regs.enable().write(|w| w.set_enable(true)); |
| 185 | 185 | ||
| 186 | // Wait until the peripheral is ready. | 186 | // Wait until the peripheral is ready. |
| 187 | regs.intenset.write(|w| w.usbevent().set_bit()); | 187 | regs.intenset().write(|w| w.set_usbevent(true)); |
| 188 | poll_fn(|cx| { | 188 | poll_fn(|cx| { |
| 189 | BUS_WAKER.register(cx.waker()); | 189 | BUS_WAKER.register(cx.waker()); |
| 190 | if regs.eventcause.read().ready().is_ready() { | 190 | if regs.eventcause().read().ready() { |
| 191 | Poll::Ready(()) | 191 | Poll::Ready(()) |
| 192 | } else { | 192 | } else { |
| 193 | Poll::Pending | 193 | Poll::Pending |
| 194 | } | 194 | } |
| 195 | }) | 195 | }) |
| 196 | .await; | 196 | .await; |
| 197 | regs.eventcause.write(|w| w.ready().clear_bit_by_one()); | 197 | regs.eventcause().write(|w| w.set_ready(true)); |
| 198 | 198 | ||
| 199 | errata::post_enable(); | 199 | errata::post_enable(); |
| 200 | 200 | ||
| 201 | unsafe { NVIC::unmask(pac::Interrupt::USBD) }; | 201 | unsafe { NVIC::unmask(pac::Interrupt::USBD) }; |
| 202 | 202 | ||
| 203 | regs.intenset.write(|w| { | 203 | regs.intenset().write(|w| { |
| 204 | w.usbreset().set_bit(); | 204 | w.set_usbreset(true); |
| 205 | w.usbevent().set_bit(); | 205 | w.set_usbevent(true); |
| 206 | w.epdata().set_bit(); | 206 | w.set_epdata(true); |
| 207 | w | ||
| 208 | }); | 207 | }); |
| 209 | 208 | ||
| 210 | if self.vbus_detect.wait_power_ready().await.is_ok() { | 209 | if self.vbus_detect.wait_power_ready().await.is_ok() { |
| 211 | // Enable the USB pullup, allowing enumeration. | 210 | // Enable the USB pullup, allowing enumeration. |
| 212 | regs.usbpullup.write(|w| w.connect().enabled()); | 211 | regs.usbpullup().write(|w| w.set_connect(true)); |
| 213 | trace!("enabled"); | 212 | trace!("enabled"); |
| 214 | } else { | 213 | } else { |
| 215 | trace!("usb power not ready due to usb removal"); | 214 | trace!("usb power not ready due to usb removal"); |
| @@ -218,7 +217,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 218 | 217 | ||
| 219 | async fn disable(&mut self) { | 218 | async fn disable(&mut self) { |
| 220 | let regs = T::regs(); | 219 | let regs = T::regs(); |
| 221 | regs.enable.write(|x| x.enable().disabled()); | 220 | regs.enable().write(|x| x.set_enable(false)); |
| 222 | } | 221 | } |
| 223 | 222 | ||
| 224 | async fn poll(&mut self) -> Event { | 223 | async fn poll(&mut self) -> Event { |
| @@ -226,13 +225,13 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 226 | BUS_WAKER.register(cx.waker()); | 225 | BUS_WAKER.register(cx.waker()); |
| 227 | let regs = T::regs(); | 226 | let regs = T::regs(); |
| 228 | 227 | ||
| 229 | if regs.events_usbreset.read().bits() != 0 { | 228 | if regs.events_usbreset().read() != 0 { |
| 230 | regs.events_usbreset.reset(); | 229 | regs.events_usbreset().write_value(0); |
| 231 | regs.intenset.write(|w| w.usbreset().set()); | 230 | regs.intenset().write(|w| w.set_usbreset(true)); |
| 232 | 231 | ||
| 233 | // Disable all endpoints except EP0 | 232 | // Disable all endpoints except EP0 |
| 234 | regs.epinen.write(|w| unsafe { w.bits(0x01) }); | 233 | regs.epinen().write(|w| w.0 = 0x01); |
| 235 | regs.epouten.write(|w| unsafe { w.bits(0x01) }); | 234 | regs.epouten().write(|w| w.0 = 0x01); |
| 236 | READY_ENDPOINTS.store(In::mask(0), Ordering::Release); | 235 | READY_ENDPOINTS.store(In::mask(0), Ordering::Release); |
| 237 | for i in 1..=7 { | 236 | for i in 1..=7 { |
| 238 | In::waker(i).wake(); | 237 | In::waker(i).wake(); |
| @@ -242,27 +241,27 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 242 | return Poll::Ready(Event::Reset); | 241 | return Poll::Ready(Event::Reset); |
| 243 | } | 242 | } |
| 244 | 243 | ||
| 245 | let r = regs.eventcause.read(); | 244 | let r = regs.eventcause().read(); |
| 246 | 245 | ||
| 247 | if r.isooutcrc().bit() { | 246 | if r.isooutcrc() { |
| 248 | regs.eventcause.write(|w| w.isooutcrc().detected()); | 247 | regs.eventcause().write(|w| w.set_isooutcrc(true)); |
| 249 | trace!("USB event: isooutcrc"); | 248 | trace!("USB event: isooutcrc"); |
| 250 | } | 249 | } |
| 251 | if r.usbwuallowed().bit() { | 250 | if r.usbwuallowed() { |
| 252 | regs.eventcause.write(|w| w.usbwuallowed().allowed()); | 251 | regs.eventcause().write(|w| w.set_usbwuallowed(true)); |
| 253 | trace!("USB event: usbwuallowed"); | 252 | trace!("USB event: usbwuallowed"); |
| 254 | } | 253 | } |
| 255 | if r.suspend().bit() { | 254 | if r.suspend() { |
| 256 | regs.eventcause.write(|w| w.suspend().detected()); | 255 | regs.eventcause().write(|w| w.set_suspend(true)); |
| 257 | regs.lowpower.write(|w| w.lowpower().low_power()); | 256 | regs.lowpower().write(|w| w.set_lowpower(vals::Lowpower::LOW_POWER)); |
| 258 | return Poll::Ready(Event::Suspend); | 257 | return Poll::Ready(Event::Suspend); |
| 259 | } | 258 | } |
| 260 | if r.resume().bit() { | 259 | if r.resume() { |
| 261 | regs.eventcause.write(|w| w.resume().detected()); | 260 | regs.eventcause().write(|w| w.set_resume(true)); |
| 262 | return Poll::Ready(Event::Resume); | 261 | return Poll::Ready(Event::Resume); |
| 263 | } | 262 | } |
| 264 | if r.ready().bit() { | 263 | if r.ready() { |
| 265 | regs.eventcause.write(|w| w.ready().ready()); | 264 | regs.eventcause().write(|w| w.set_ready(true)); |
| 266 | trace!("USB event: ready"); | 265 | trace!("USB event: ready"); |
| 267 | } | 266 | } |
| 268 | 267 | ||
| @@ -284,16 +283,19 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 284 | 283 | ||
| 285 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { | 284 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { |
| 286 | let regs = T::regs(); | 285 | let regs = T::regs(); |
| 287 | unsafe { | 286 | if ep_addr.index() == 0 { |
| 288 | if ep_addr.index() == 0 { | 287 | if stalled { |
| 289 | regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(stalled)); | 288 | regs.tasks_ep0stall().write_value(1); |
| 290 | } else { | ||
| 291 | regs.epstall.write(|w| { | ||
| 292 | w.ep().bits(ep_addr.index() as u8 & 0b111); | ||
| 293 | w.io().bit(ep_addr.is_in()); | ||
| 294 | w.stall().bit(stalled) | ||
| 295 | }); | ||
| 296 | } | 289 | } |
| 290 | } else { | ||
| 291 | regs.epstall().write(|w| { | ||
| 292 | w.set_ep(ep_addr.index() as u8 & 0b111); | ||
| 293 | w.set_io(match ep_addr.direction() { | ||
| 294 | Direction::In => vals::Io::IN, | ||
| 295 | Direction::Out => vals::Io::OUT, | ||
| 296 | }); | ||
| 297 | w.set_stall(stalled); | ||
| 298 | }); | ||
| 297 | } | 299 | } |
| 298 | } | 300 | } |
| 299 | 301 | ||
| @@ -301,8 +303,8 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 301 | let regs = T::regs(); | 303 | let regs = T::regs(); |
| 302 | let i = ep_addr.index(); | 304 | let i = ep_addr.index(); |
| 303 | match ep_addr.direction() { | 305 | match ep_addr.direction() { |
| 304 | Direction::Out => regs.halted.epout[i].read().getstatus().is_halted(), | 306 | Direction::Out => regs.halted().epout(i).read().getstatus() == vals::Getstatus::HALTED, |
| 305 | Direction::In => regs.halted.epin[i].read().getstatus().is_halted(), | 307 | Direction::In => regs.halted().epin(i).read().getstatus() == vals::Getstatus::HALTED, |
| 306 | } | 308 | } |
| 307 | } | 309 | } |
| 308 | 310 | ||
| @@ -317,15 +319,13 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 317 | match ep_addr.direction() { | 319 | match ep_addr.direction() { |
| 318 | Direction::In => { | 320 | Direction::In => { |
| 319 | let mut was_enabled = false; | 321 | let mut was_enabled = false; |
| 320 | regs.epinen.modify(|r, w| { | 322 | regs.epinen().modify(|w| { |
| 321 | let mut bits = r.bits(); | 323 | was_enabled = (w.0 & mask) != 0; |
| 322 | was_enabled = (bits & mask) != 0; | ||
| 323 | if enabled { | 324 | if enabled { |
| 324 | bits |= mask | 325 | w.0 |= mask |
| 325 | } else { | 326 | } else { |
| 326 | bits &= !mask | 327 | w.0 &= !mask |
| 327 | } | 328 | } |
| 328 | unsafe { w.bits(bits) } | ||
| 329 | }); | 329 | }); |
| 330 | 330 | ||
| 331 | let ready_mask = In::mask(i); | 331 | let ready_mask = In::mask(i); |
| @@ -340,15 +340,8 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 340 | In::waker(i).wake(); | 340 | In::waker(i).wake(); |
| 341 | } | 341 | } |
| 342 | Direction::Out => { | 342 | Direction::Out => { |
| 343 | regs.epouten.modify(|r, w| { | 343 | regs.epouten() |
| 344 | let mut bits = r.bits(); | 344 | .modify(|w| if enabled { w.0 |= mask } else { w.0 &= !mask }); |
| 345 | if enabled { | ||
| 346 | bits |= mask | ||
| 347 | } else { | ||
| 348 | bits &= !mask | ||
| 349 | } | ||
| 350 | unsafe { w.bits(bits) } | ||
| 351 | }); | ||
| 352 | 345 | ||
| 353 | let ready_mask = Out::mask(i); | 346 | let ready_mask = Out::mask(i); |
| 354 | if enabled { | 347 | if enabled { |
| @@ -356,7 +349,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 356 | // peripheral will NAK all incoming packets) until we write a zero to the SIZE | 349 | // peripheral will NAK all incoming packets) until we write a zero to the SIZE |
| 357 | // register (see figure 203 of the 52840 manual). To avoid that we write a 0 to the | 350 | // register (see figure 203 of the 52840 manual). To avoid that we write a 0 to the |
| 358 | // SIZE register | 351 | // SIZE register |
| 359 | regs.size.epout[i].reset(); | 352 | regs.size().epout(i).write(|_| ()); |
| 360 | } else { | 353 | } else { |
| 361 | READY_ENDPOINTS.fetch_and(!ready_mask, Ordering::AcqRel); | 354 | READY_ENDPOINTS.fetch_and(!ready_mask, Ordering::AcqRel); |
| 362 | } | 355 | } |
| @@ -370,25 +363,24 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 370 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { | 363 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { |
| 371 | let regs = T::regs(); | 364 | let regs = T::regs(); |
| 372 | 365 | ||
| 373 | if regs.lowpower.read().lowpower().is_low_power() { | 366 | if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER { |
| 374 | errata::pre_wakeup(); | 367 | errata::pre_wakeup(); |
| 375 | 368 | ||
| 376 | regs.lowpower.write(|w| w.lowpower().force_normal()); | 369 | regs.lowpower().write(|w| w.set_lowpower(vals::Lowpower::FORCE_NORMAL)); |
| 377 | 370 | ||
| 378 | poll_fn(|cx| { | 371 | poll_fn(|cx| { |
| 379 | BUS_WAKER.register(cx.waker()); | 372 | BUS_WAKER.register(cx.waker()); |
| 380 | let regs = T::regs(); | 373 | let regs = T::regs(); |
| 381 | let r = regs.eventcause.read(); | 374 | let r = regs.eventcause().read(); |
| 382 | 375 | ||
| 383 | if regs.events_usbreset.read().bits() != 0 { | 376 | if regs.events_usbreset().read() != 0 { |
| 384 | Poll::Ready(()) | 377 | Poll::Ready(()) |
| 385 | } else if r.resume().bit() { | 378 | } else if r.resume() { |
| 386 | Poll::Ready(()) | 379 | Poll::Ready(()) |
| 387 | } else if r.usbwuallowed().bit() { | 380 | } else if r.usbwuallowed() { |
| 388 | regs.eventcause.write(|w| w.usbwuallowed().allowed()); | 381 | regs.eventcause().write(|w| w.set_usbwuallowed(true)); |
| 389 | 382 | regs.dpdmvalue().write(|w| w.set_state(vals::State::RESUME)); | |
| 390 | regs.dpdmvalue.write(|w| w.state().resume()); | 383 | regs.tasks_dpdmdrive().write_value(1); |
| 391 | regs.tasks_dpdmdrive.write(|w| w.tasks_dpdmdrive().set_bit()); | ||
| 392 | 384 | ||
| 393 | Poll::Ready(()) | 385 | Poll::Ready(()) |
| 394 | } else { | 386 | } else { |
| @@ -413,7 +405,7 @@ pub enum In {} | |||
| 413 | trait EndpointDir { | 405 | trait EndpointDir { |
| 414 | fn waker(i: usize) -> &'static AtomicWaker; | 406 | fn waker(i: usize) -> &'static AtomicWaker; |
| 415 | fn mask(i: usize) -> u32; | 407 | fn mask(i: usize) -> u32; |
| 416 | fn is_enabled(regs: &RegisterBlock, i: usize) -> bool; | 408 | fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool; |
| 417 | } | 409 | } |
| 418 | 410 | ||
| 419 | impl EndpointDir for In { | 411 | impl EndpointDir for In { |
| @@ -428,8 +420,8 @@ impl EndpointDir for In { | |||
| 428 | } | 420 | } |
| 429 | 421 | ||
| 430 | #[inline] | 422 | #[inline] |
| 431 | fn is_enabled(regs: &RegisterBlock, i: usize) -> bool { | 423 | fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool { |
| 432 | (regs.epinen.read().bits() & (1 << i)) != 0 | 424 | regs.epinen().read().in_(i) |
| 433 | } | 425 | } |
| 434 | } | 426 | } |
| 435 | 427 | ||
| @@ -445,8 +437,8 @@ impl EndpointDir for Out { | |||
| 445 | } | 437 | } |
| 446 | 438 | ||
| 447 | #[inline] | 439 | #[inline] |
| 448 | fn is_enabled(regs: &RegisterBlock, i: usize) -> bool { | 440 | fn is_enabled(regs: pac::usbd::Usbd, i: usize) -> bool { |
| 449 | (regs.epouten.read().bits() & (1 << i)) != 0 | 441 | regs.epouten().read().out(i) |
| 450 | } | 442 | } |
| 451 | } | 443 | } |
| 452 | 444 | ||
| @@ -529,33 +521,23 @@ unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, Endpo | |||
| 529 | let regs = T::regs(); | 521 | let regs = T::regs(); |
| 530 | 522 | ||
| 531 | // Check that the packet fits into the buffer | 523 | // Check that the packet fits into the buffer |
| 532 | let size = regs.size.epout[i].read().bits() as usize; | 524 | let size = regs.size().epout(i).read().0 as usize; |
| 533 | if size > buf.len() { | 525 | if size > buf.len() { |
| 534 | return Err(EndpointError::BufferOverflow); | 526 | return Err(EndpointError::BufferOverflow); |
| 535 | } | 527 | } |
| 536 | 528 | ||
| 537 | let epout = [ | 529 | regs.epout(i).ptr().write_value(buf.as_ptr() as u32); |
| 538 | ®s.epout0, | ||
| 539 | ®s.epout1, | ||
| 540 | ®s.epout2, | ||
| 541 | ®s.epout3, | ||
| 542 | ®s.epout4, | ||
| 543 | ®s.epout5, | ||
| 544 | ®s.epout6, | ||
| 545 | ®s.epout7, | ||
| 546 | ]; | ||
| 547 | epout[i].ptr.write(|w| w.bits(buf.as_ptr() as u32)); | ||
| 548 | // MAXCNT must match SIZE | 530 | // MAXCNT must match SIZE |
| 549 | epout[i].maxcnt.write(|w| w.bits(size as u32)); | 531 | regs.epout(i).maxcnt().write(|w| w.set_maxcnt(size as _)); |
| 550 | 532 | ||
| 551 | dma_start(); | 533 | dma_start(); |
| 552 | regs.events_endepout[i].reset(); | 534 | regs.events_endepout(i).write_value(0); |
| 553 | regs.tasks_startepout[i].write(|w| w.tasks_startepout().set_bit()); | 535 | regs.tasks_startepout(i).write_value(1); |
| 554 | while regs.events_endepout[i].read().events_endepout().bit_is_clear() {} | 536 | while regs.events_endepout(i).read() == 0 {} |
| 555 | regs.events_endepout[i].reset(); | 537 | regs.events_endepout(i).write_value(0); |
| 556 | dma_end(); | 538 | dma_end(); |
| 557 | 539 | ||
| 558 | regs.size.epout[i].reset(); | 540 | regs.size().epout(i).write(|_| ()); |
| 559 | 541 | ||
| 560 | Ok(size) | 542 | Ok(size) |
| 561 | } | 543 | } |
| @@ -574,27 +556,16 @@ unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) { | |||
| 574 | buf.as_ptr() | 556 | buf.as_ptr() |
| 575 | }; | 557 | }; |
| 576 | 558 | ||
| 577 | let epin = [ | ||
| 578 | ®s.epin0, | ||
| 579 | ®s.epin1, | ||
| 580 | ®s.epin2, | ||
| 581 | ®s.epin3, | ||
| 582 | ®s.epin4, | ||
| 583 | ®s.epin5, | ||
| 584 | ®s.epin6, | ||
| 585 | ®s.epin7, | ||
| 586 | ]; | ||
| 587 | |||
| 588 | // Set the buffer length so the right number of bytes are transmitted. | 559 | // Set the buffer length so the right number of bytes are transmitted. |
| 589 | // Safety: `buf.len()` has been checked to be <= the max buffer length. | 560 | // Safety: `buf.len()` has been checked to be <= the max buffer length. |
| 590 | epin[i].ptr.write(|w| w.bits(ptr as u32)); | 561 | regs.epin(i).ptr().write_value(ptr as u32); |
| 591 | epin[i].maxcnt.write(|w| w.maxcnt().bits(buf.len() as u8)); | 562 | regs.epin(i).maxcnt().write(|w| w.set_maxcnt(buf.len() as u8)); |
| 592 | 563 | ||
| 593 | regs.events_endepin[i].reset(); | 564 | regs.events_endepin(i).write_value(0); |
| 594 | 565 | ||
| 595 | dma_start(); | 566 | dma_start(); |
| 596 | regs.tasks_startepin[i].write(|w| w.bits(1)); | 567 | regs.tasks_startepin(i).write_value(1); |
| 597 | while regs.events_endepin[i].read().bits() == 0 {} | 568 | while regs.events_endepin(i).read() == 0 {} |
| 598 | dma_end(); | 569 | dma_end(); |
| 599 | } | 570 | } |
| 600 | 571 | ||
| @@ -637,14 +608,14 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 637 | let regs = T::regs(); | 608 | let regs = T::regs(); |
| 638 | 609 | ||
| 639 | // Reset shorts | 610 | // Reset shorts |
| 640 | regs.shorts.write(|w| w); | 611 | regs.shorts().write(|_| ()); |
| 641 | 612 | ||
| 642 | // Wait for SETUP packet | 613 | // Wait for SETUP packet |
| 643 | regs.intenset.write(|w| w.ep0setup().set()); | 614 | regs.intenset().write(|w| w.set_ep0setup(true)); |
| 644 | poll_fn(|cx| { | 615 | poll_fn(|cx| { |
| 645 | EP0_WAKER.register(cx.waker()); | 616 | EP0_WAKER.register(cx.waker()); |
| 646 | let regs = T::regs(); | 617 | let regs = T::regs(); |
| 647 | if regs.events_ep0setup.read().bits() != 0 { | 618 | if regs.events_ep0setup().read() != 0 { |
| 648 | Poll::Ready(()) | 619 | Poll::Ready(()) |
| 649 | } else { | 620 | } else { |
| 650 | Poll::Pending | 621 | Poll::Pending |
| @@ -652,17 +623,17 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 652 | }) | 623 | }) |
| 653 | .await; | 624 | .await; |
| 654 | 625 | ||
| 655 | regs.events_ep0setup.reset(); | 626 | regs.events_ep0setup().write_value(0); |
| 656 | 627 | ||
| 657 | let mut buf = [0; 8]; | 628 | let mut buf = [0; 8]; |
| 658 | buf[0] = regs.bmrequesttype.read().bits() as u8; | 629 | buf[0] = regs.bmrequesttype().read().0 as u8; |
| 659 | buf[1] = regs.brequest.read().brequest().bits(); | 630 | buf[1] = regs.brequest().read().0 as u8; |
| 660 | buf[2] = regs.wvaluel.read().wvaluel().bits(); | 631 | buf[2] = regs.wvaluel().read().0 as u8; |
| 661 | buf[3] = regs.wvalueh.read().wvalueh().bits(); | 632 | buf[3] = regs.wvalueh().read().0 as u8; |
| 662 | buf[4] = regs.windexl.read().windexl().bits(); | 633 | buf[4] = regs.windexl().read().0 as u8; |
| 663 | buf[5] = regs.windexh.read().windexh().bits(); | 634 | buf[5] = regs.windexh().read().0 as u8; |
| 664 | buf[6] = regs.wlengthl.read().wlengthl().bits(); | 635 | buf[6] = regs.wlengthl().read().0 as u8; |
| 665 | buf[7] = regs.wlengthh.read().wlengthh().bits(); | 636 | buf[7] = regs.wlengthh().read().0 as u8; |
| 666 | 637 | ||
| 667 | buf | 638 | buf |
| 668 | } | 639 | } |
| @@ -670,26 +641,26 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 670 | async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { | 641 | async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { |
| 671 | let regs = T::regs(); | 642 | let regs = T::regs(); |
| 672 | 643 | ||
| 673 | regs.events_ep0datadone.reset(); | 644 | regs.events_ep0datadone().write_value(0); |
| 674 | 645 | ||
| 675 | // This starts a RX on EP0. events_ep0datadone notifies when done. | 646 | // This starts a RX on EP0. events_ep0datadone notifies when done. |
| 676 | regs.tasks_ep0rcvout.write(|w| w.tasks_ep0rcvout().set_bit()); | 647 | regs.tasks_ep0rcvout().write_value(1); |
| 677 | 648 | ||
| 678 | // Wait until ready | 649 | // Wait until ready |
| 679 | regs.intenset.write(|w| { | 650 | regs.intenset().write(|w| { |
| 680 | w.usbreset().set(); | 651 | w.set_usbreset(true); |
| 681 | w.ep0setup().set(); | 652 | w.set_ep0setup(true); |
| 682 | w.ep0datadone().set() | 653 | w.set_ep0datadone(true); |
| 683 | }); | 654 | }); |
| 684 | poll_fn(|cx| { | 655 | poll_fn(|cx| { |
| 685 | EP0_WAKER.register(cx.waker()); | 656 | EP0_WAKER.register(cx.waker()); |
| 686 | let regs = T::regs(); | 657 | let regs = T::regs(); |
| 687 | if regs.events_ep0datadone.read().bits() != 0 { | 658 | if regs.events_ep0datadone().read() != 0 { |
| 688 | Poll::Ready(Ok(())) | 659 | Poll::Ready(Ok(())) |
| 689 | } else if regs.events_usbreset.read().bits() != 0 { | 660 | } else if regs.events_usbreset().read() != 0 { |
| 690 | trace!("aborted control data_out: usb reset"); | 661 | trace!("aborted control data_out: usb reset"); |
| 691 | Poll::Ready(Err(EndpointError::Disabled)) | 662 | Poll::Ready(Err(EndpointError::Disabled)) |
| 692 | } else if regs.events_ep0setup.read().bits() != 0 { | 663 | } else if regs.events_ep0setup().read() != 0 { |
| 693 | trace!("aborted control data_out: received another SETUP"); | 664 | trace!("aborted control data_out: received another SETUP"); |
| 694 | Poll::Ready(Err(EndpointError::Disabled)) | 665 | Poll::Ready(Err(EndpointError::Disabled)) |
| 695 | } else { | 666 | } else { |
| @@ -703,29 +674,29 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 703 | 674 | ||
| 704 | async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { | 675 | async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { |
| 705 | let regs = T::regs(); | 676 | let regs = T::regs(); |
| 706 | regs.events_ep0datadone.reset(); | 677 | regs.events_ep0datadone().write_value(0); |
| 707 | 678 | ||
| 708 | regs.shorts.write(|w| w.ep0datadone_ep0status().bit(last)); | 679 | regs.shorts().write(|w| w.set_ep0datadone_ep0status(last)); |
| 709 | 680 | ||
| 710 | // This starts a TX on EP0. events_ep0datadone notifies when done. | 681 | // This starts a TX on EP0. events_ep0datadone notifies when done. |
| 711 | unsafe { write_dma::<T>(0, buf) } | 682 | unsafe { write_dma::<T>(0, buf) } |
| 712 | 683 | ||
| 713 | regs.intenset.write(|w| { | 684 | regs.intenset().write(|w| { |
| 714 | w.usbreset().set(); | 685 | w.set_usbreset(true); |
| 715 | w.ep0setup().set(); | 686 | w.set_ep0setup(true); |
| 716 | w.ep0datadone().set() | 687 | w.set_ep0datadone(true); |
| 717 | }); | 688 | }); |
| 718 | 689 | ||
| 719 | poll_fn(|cx| { | 690 | poll_fn(|cx| { |
| 720 | cx.waker().wake_by_ref(); | 691 | cx.waker().wake_by_ref(); |
| 721 | EP0_WAKER.register(cx.waker()); | 692 | EP0_WAKER.register(cx.waker()); |
| 722 | let regs = T::regs(); | 693 | let regs = T::regs(); |
| 723 | if regs.events_ep0datadone.read().bits() != 0 { | 694 | if regs.events_ep0datadone().read() != 0 { |
| 724 | Poll::Ready(Ok(())) | 695 | Poll::Ready(Ok(())) |
| 725 | } else if regs.events_usbreset.read().bits() != 0 { | 696 | } else if regs.events_usbreset().read() != 0 { |
| 726 | trace!("aborted control data_in: usb reset"); | 697 | trace!("aborted control data_in: usb reset"); |
| 727 | Poll::Ready(Err(EndpointError::Disabled)) | 698 | Poll::Ready(Err(EndpointError::Disabled)) |
| 728 | } else if regs.events_ep0setup.read().bits() != 0 { | 699 | } else if regs.events_ep0setup().read() != 0 { |
| 729 | trace!("aborted control data_in: received another SETUP"); | 700 | trace!("aborted control data_in: received another SETUP"); |
| 730 | Poll::Ready(Err(EndpointError::Disabled)) | 701 | Poll::Ready(Err(EndpointError::Disabled)) |
| 731 | } else { | 702 | } else { |
| @@ -737,12 +708,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 737 | 708 | ||
| 738 | async fn accept(&mut self) { | 709 | async fn accept(&mut self) { |
| 739 | let regs = T::regs(); | 710 | let regs = T::regs(); |
| 740 | regs.tasks_ep0status.write(|w| w.tasks_ep0status().bit(true)); | 711 | regs.tasks_ep0status().write_value(1); |
| 741 | } | 712 | } |
| 742 | 713 | ||
| 743 | async fn reject(&mut self) { | 714 | async fn reject(&mut self) { |
| 744 | let regs = T::regs(); | 715 | let regs = T::regs(); |
| 745 | regs.tasks_ep0stall.write(|w| w.tasks_ep0stall().bit(true)); | 716 | regs.tasks_ep0stall().write_value(1); |
| 746 | } | 717 | } |
| 747 | 718 | ||
| 748 | async fn accept_set_address(&mut self, _addr: u8) { | 719 | async fn accept_set_address(&mut self, _addr: u8) { |
| @@ -806,7 +777,7 @@ impl Allocator { | |||
| 806 | } | 777 | } |
| 807 | 778 | ||
| 808 | pub(crate) trait SealedInstance { | 779 | pub(crate) trait SealedInstance { |
| 809 | fn regs() -> &'static pac::usbd::RegisterBlock; | 780 | fn regs() -> pac::usbd::Usbd; |
| 810 | } | 781 | } |
| 811 | 782 | ||
| 812 | /// USB peripheral instance. | 783 | /// USB peripheral instance. |
| @@ -819,8 +790,8 @@ pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send { | |||
| 819 | macro_rules! impl_usb { | 790 | macro_rules! impl_usb { |
| 820 | ($type:ident, $pac_type:ident, $irq:ident) => { | 791 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 821 | impl crate::usb::SealedInstance for peripherals::$type { | 792 | impl crate::usb::SealedInstance for peripherals::$type { |
| 822 | fn regs() -> &'static pac::usbd::RegisterBlock { | 793 | fn regs() -> pac::usbd::Usbd { |
| 823 | unsafe { &*pac::$pac_type::ptr() } | 794 | pac::$pac_type |
| 824 | } | 795 | } |
| 825 | } | 796 | } |
| 826 | impl crate::usb::Instance for peripherals::$type { | 797 | impl crate::usb::Instance for peripherals::$type { |
diff --git a/embassy-nrf/src/usb/vbus_detect.rs b/embassy-nrf/src/usb/vbus_detect.rs index a05e5aa52..7f816a5ad 100644 --- a/embassy-nrf/src/usb/vbus_detect.rs +++ b/embassy-nrf/src/usb/vbus_detect.rs | |||
| @@ -34,9 +34,9 @@ type UsbRegIrq = interrupt::typelevel::POWER_CLOCK; | |||
| 34 | type UsbRegIrq = interrupt::typelevel::USBREGULATOR; | 34 | type UsbRegIrq = interrupt::typelevel::USBREGULATOR; |
| 35 | 35 | ||
| 36 | #[cfg(not(feature = "_nrf5340"))] | 36 | #[cfg(not(feature = "_nrf5340"))] |
| 37 | type UsbRegPeri = pac::POWER; | 37 | const USB_REG_PERI: pac::power::Power = pac::POWER; |
| 38 | #[cfg(feature = "_nrf5340")] | 38 | #[cfg(feature = "_nrf5340")] |
| 39 | type UsbRegPeri = pac::USBREGULATOR; | 39 | const USB_REG_PERI: pac::usbregulator::Usbregulator = pac::USBREGULATOR; |
| 40 | 40 | ||
| 41 | /// Interrupt handler. | 41 | /// Interrupt handler. |
| 42 | pub struct InterruptHandler { | 42 | pub struct InterruptHandler { |
| @@ -45,21 +45,21 @@ pub struct InterruptHandler { | |||
| 45 | 45 | ||
| 46 | impl interrupt::typelevel::Handler<UsbRegIrq> for InterruptHandler { | 46 | impl interrupt::typelevel::Handler<UsbRegIrq> for InterruptHandler { |
| 47 | unsafe fn on_interrupt() { | 47 | unsafe fn on_interrupt() { |
| 48 | let regs = unsafe { &*UsbRegPeri::ptr() }; | 48 | let regs = USB_REG_PERI; |
| 49 | 49 | ||
| 50 | if regs.events_usbdetected.read().bits() != 0 { | 50 | if regs.events_usbdetected().read() != 0 { |
| 51 | regs.events_usbdetected.reset(); | 51 | regs.events_usbdetected().write_value(0); |
| 52 | BUS_WAKER.wake(); | 52 | BUS_WAKER.wake(); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | if regs.events_usbremoved.read().bits() != 0 { | 55 | if regs.events_usbremoved().read() != 0 { |
| 56 | regs.events_usbremoved.reset(); | 56 | regs.events_usbremoved().write_value(0); |
| 57 | BUS_WAKER.wake(); | 57 | BUS_WAKER.wake(); |
| 58 | POWER_WAKER.wake(); | 58 | POWER_WAKER.wake(); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | if regs.events_usbpwrrdy.read().bits() != 0 { | 61 | if regs.events_usbpwrrdy().read() != 0 { |
| 62 | regs.events_usbpwrrdy.reset(); | 62 | regs.events_usbpwrrdy().write_value(0); |
| 63 | POWER_WAKER.wake(); | 63 | POWER_WAKER.wake(); |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| @@ -78,13 +78,16 @@ static POWER_WAKER: AtomicWaker = AtomicWaker::new(); | |||
| 78 | impl HardwareVbusDetect { | 78 | impl HardwareVbusDetect { |
| 79 | /// Create a new `VbusDetectNative`. | 79 | /// Create a new `VbusDetectNative`. |
| 80 | pub fn new(_irq: impl interrupt::typelevel::Binding<UsbRegIrq, InterruptHandler> + 'static) -> Self { | 80 | pub fn new(_irq: impl interrupt::typelevel::Binding<UsbRegIrq, InterruptHandler> + 'static) -> Self { |
| 81 | let regs = unsafe { &*UsbRegPeri::ptr() }; | 81 | let regs = USB_REG_PERI; |
| 82 | 82 | ||
| 83 | UsbRegIrq::unpend(); | 83 | UsbRegIrq::unpend(); |
| 84 | unsafe { UsbRegIrq::enable() }; | 84 | unsafe { UsbRegIrq::enable() }; |
| 85 | 85 | ||
| 86 | regs.intenset | 86 | regs.intenset().write(|w| { |
| 87 | .write(|w| w.usbdetected().set().usbremoved().set().usbpwrrdy().set()); | 87 | w.set_usbdetected(true); |
| 88 | w.set_usbremoved(true); | ||
| 89 | w.set_usbpwrrdy(true); | ||
| 90 | }); | ||
| 88 | 91 | ||
| 89 | Self { _private: () } | 92 | Self { _private: () } |
| 90 | } | 93 | } |
| @@ -92,16 +95,16 @@ impl HardwareVbusDetect { | |||
| 92 | 95 | ||
| 93 | impl VbusDetect for HardwareVbusDetect { | 96 | impl VbusDetect for HardwareVbusDetect { |
| 94 | fn is_usb_detected(&self) -> bool { | 97 | fn is_usb_detected(&self) -> bool { |
| 95 | let regs = unsafe { &*UsbRegPeri::ptr() }; | 98 | let regs = USB_REG_PERI; |
| 96 | regs.usbregstatus.read().vbusdetect().is_vbus_present() | 99 | regs.usbregstatus().read().vbusdetect() |
| 97 | } | 100 | } |
| 98 | 101 | ||
| 99 | async fn wait_power_ready(&mut self) -> Result<(), ()> { | 102 | async fn wait_power_ready(&mut self) -> Result<(), ()> { |
| 100 | poll_fn(move |cx| { | 103 | poll_fn(move |cx| { |
| 101 | POWER_WAKER.register(cx.waker()); | 104 | POWER_WAKER.register(cx.waker()); |
| 102 | let regs = unsafe { &*UsbRegPeri::ptr() }; | 105 | let regs = USB_REG_PERI; |
| 103 | 106 | ||
| 104 | if regs.usbregstatus.read().outputrdy().is_ready() { | 107 | if regs.usbregstatus().read().outputrdy() { |
| 105 | Poll::Ready(Ok(())) | 108 | Poll::Ready(Ok(())) |
| 106 | } else if !self.is_usb_detected() { | 109 | } else if !self.is_usb_detected() { |
| 107 | Poll::Ready(Err(())) | 110 | Poll::Ready(Err(())) |
diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index e4cfa3344..dfe6cbec3 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs | |||
| @@ -3,7 +3,8 @@ | |||
| 3 | //! This HAL implements a basic watchdog timer with 1..=8 handles. | 3 | //! This HAL implements a basic watchdog timer with 1..=8 handles. |
| 4 | //! Once the watchdog has been started, it cannot be stopped. | 4 | //! Once the watchdog has been started, it cannot be stopped. |
| 5 | 5 | ||
| 6 | use crate::pac::WDT; | 6 | use crate::pac::wdt::vals; |
| 7 | pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; | ||
| 7 | use crate::peripherals; | 8 | use crate::peripherals; |
| 8 | 9 | ||
| 9 | const MIN_TICKS: u32 = 15; | 10 | const MIN_TICKS: u32 = 15; |
| @@ -18,29 +19,29 @@ pub struct Config { | |||
| 18 | pub timeout_ticks: u32, | 19 | pub timeout_ticks: u32, |
| 19 | 20 | ||
| 20 | /// Should the watchdog continue to count during sleep modes? | 21 | /// Should the watchdog continue to count during sleep modes? |
| 21 | pub run_during_sleep: bool, | 22 | pub action_during_sleep: SleepConfig, |
| 22 | 23 | ||
| 23 | /// Should the watchdog continue to count when the CPU is halted for debug? | 24 | /// Should the watchdog continue to count when the CPU is halted for debug? |
| 24 | pub run_during_debug_halt: bool, | 25 | pub action_during_debug_halt: HaltConfig, |
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | impl Config { | 28 | impl Config { |
| 28 | /// Create a config structure from the current configuration of the WDT | 29 | /// Create a config structure from the current configuration of the WDT |
| 29 | /// peripheral. | 30 | /// peripheral. |
| 30 | pub fn try_new(_wdt: &peripherals::WDT) -> Option<Self> { | 31 | pub fn try_new(_wdt: &peripherals::WDT) -> Option<Self> { |
| 31 | let r = unsafe { &*WDT::ptr() }; | 32 | let r = crate::pac::WDT; |
| 32 | 33 | ||
| 33 | #[cfg(not(feature = "_nrf91"))] | 34 | #[cfg(not(feature = "_nrf91"))] |
| 34 | let runstatus = r.runstatus.read().runstatus().bit(); | 35 | let runstatus = r.runstatus().read().runstatus(); |
| 35 | #[cfg(feature = "_nrf91")] | 36 | #[cfg(feature = "_nrf91")] |
| 36 | let runstatus = r.runstatus.read().runstatuswdt().bit(); | 37 | let runstatus = r.runstatus().read().runstatuswdt(); |
| 37 | 38 | ||
| 38 | if runstatus { | 39 | if runstatus { |
| 39 | let config = r.config.read(); | 40 | let config = r.config().read(); |
| 40 | Some(Self { | 41 | Some(Self { |
| 41 | timeout_ticks: r.crv.read().bits(), | 42 | timeout_ticks: r.crv().read(), |
| 42 | run_during_sleep: config.sleep().bit(), | 43 | action_during_sleep: config.sleep(), |
| 43 | run_during_debug_halt: config.halt().bit(), | 44 | action_during_debug_halt: config.halt(), |
| 44 | }) | 45 | }) |
| 45 | } else { | 46 | } else { |
| 46 | None | 47 | None |
| @@ -52,8 +53,8 @@ impl Default for Config { | |||
| 52 | fn default() -> Self { | 53 | fn default() -> Self { |
| 53 | Self { | 54 | Self { |
| 54 | timeout_ticks: 32768, // 1 second | 55 | timeout_ticks: 32768, // 1 second |
| 55 | run_during_debug_halt: true, | 56 | action_during_debug_halt: HaltConfig::RUN, |
| 56 | run_during_sleep: true, | 57 | action_during_sleep: SleepConfig::RUN, |
| 57 | } | 58 | } |
| 58 | } | 59 | } |
| 59 | } | 60 | } |
| @@ -78,36 +79,35 @@ impl Watchdog { | |||
| 78 | ) -> Result<(Self, [WatchdogHandle; N]), peripherals::WDT> { | 79 | ) -> Result<(Self, [WatchdogHandle; N]), peripherals::WDT> { |
| 79 | assert!(N >= 1 && N <= 8); | 80 | assert!(N >= 1 && N <= 8); |
| 80 | 81 | ||
| 81 | let r = unsafe { &*WDT::ptr() }; | 82 | let r = crate::pac::WDT; |
| 82 | 83 | ||
| 83 | let crv = config.timeout_ticks.max(MIN_TICKS); | 84 | let crv = config.timeout_ticks.max(MIN_TICKS); |
| 84 | let rren = (1u32 << N) - 1; | 85 | let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1); |
| 85 | 86 | ||
| 86 | #[cfg(not(feature = "_nrf91"))] | 87 | #[cfg(not(feature = "_nrf91"))] |
| 87 | let runstatus = r.runstatus.read().runstatus().bit(); | 88 | let runstatus = r.runstatus().read().runstatus(); |
| 88 | #[cfg(feature = "_nrf91")] | 89 | #[cfg(feature = "_nrf91")] |
| 89 | let runstatus = r.runstatus.read().runstatuswdt().bit(); | 90 | let runstatus = r.runstatus().read().runstatuswdt(); |
| 90 | 91 | ||
| 91 | if runstatus { | 92 | if runstatus { |
| 92 | let curr_config = r.config.read(); | 93 | let curr_config = r.config().read(); |
| 93 | if curr_config.halt().bit() != config.run_during_debug_halt | 94 | if curr_config.halt() != config.action_during_debug_halt |
| 94 | || curr_config.sleep().bit() != config.run_during_sleep | 95 | || curr_config.sleep() != config.action_during_sleep |
| 95 | || r.crv.read().bits() != crv | 96 | || r.crv().read() != crv |
| 96 | || r.rren.read().bits() != rren | 97 | || r.rren().read() != rren |
| 97 | { | 98 | { |
| 98 | return Err(wdt); | 99 | return Err(wdt); |
| 99 | } | 100 | } |
| 100 | } else { | 101 | } else { |
| 101 | r.config.write(|w| { | 102 | r.config().write(|w| { |
| 102 | w.sleep().bit(config.run_during_sleep); | 103 | w.set_sleep(config.action_during_sleep); |
| 103 | w.halt().bit(config.run_during_debug_halt); | 104 | w.set_halt(config.action_during_debug_halt); |
| 104 | w | ||
| 105 | }); | 105 | }); |
| 106 | r.intenset.write(|w| w.timeout().set_bit()); | 106 | r.intenset().write(|w| w.set_timeout(true)); |
| 107 | 107 | ||
| 108 | r.crv.write(|w| unsafe { w.bits(crv) }); | 108 | r.crv().write_value(crv); |
| 109 | r.rren.write(|w| unsafe { w.bits(rren) }); | 109 | r.rren().write_value(rren); |
| 110 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | 110 | r.tasks_start().write_value(1); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | let this = Self { _private: () }; | 113 | let this = Self { _private: () }; |
| @@ -130,8 +130,7 @@ impl Watchdog { | |||
| 130 | /// interrupt has been enabled. | 130 | /// interrupt has been enabled. |
| 131 | #[inline(always)] | 131 | #[inline(always)] |
| 132 | pub fn enable_interrupt(&mut self) { | 132 | pub fn enable_interrupt(&mut self) { |
| 133 | let r = unsafe { &*WDT::ptr() }; | 133 | crate::pac::WDT.intenset().write(|w| w.set_timeout(true)); |
| 134 | r.intenset.write(|w| w.timeout().set_bit()); | ||
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | /// Disable the watchdog interrupt. | 136 | /// Disable the watchdog interrupt. |
| @@ -139,8 +138,7 @@ impl Watchdog { | |||
| 139 | /// NOTE: This has no effect on the reset caused by the Watchdog. | 138 | /// NOTE: This has no effect on the reset caused by the Watchdog. |
| 140 | #[inline(always)] | 139 | #[inline(always)] |
| 141 | pub fn disable_interrupt(&mut self) { | 140 | pub fn disable_interrupt(&mut self) { |
| 142 | let r = unsafe { &*WDT::ptr() }; | 141 | crate::pac::WDT.intenclr().write(|w| w.set_timeout(true)); |
| 143 | r.intenclr.write(|w| w.timeout().set_bit()); | ||
| 144 | } | 142 | } |
| 145 | 143 | ||
| 146 | /// Is the watchdog still awaiting pets from any handle? | 144 | /// Is the watchdog still awaiting pets from any handle? |
| @@ -149,9 +147,9 @@ impl Watchdog { | |||
| 149 | /// handles to prevent a reset this time period. | 147 | /// handles to prevent a reset this time period. |
| 150 | #[inline(always)] | 148 | #[inline(always)] |
| 151 | pub fn awaiting_pets(&self) -> bool { | 149 | pub fn awaiting_pets(&self) -> bool { |
| 152 | let r = unsafe { &*WDT::ptr() }; | 150 | let r = crate::pac::WDT; |
| 153 | let enabled = r.rren.read().bits(); | 151 | let enabled = r.rren().read().0; |
| 154 | let status = r.reqstatus.read().bits(); | 152 | let status = r.reqstatus().read().0; |
| 155 | (status & enabled) == 0 | 153 | (status & enabled) == 0 |
| 156 | } | 154 | } |
| 157 | } | 155 | } |
| @@ -170,16 +168,14 @@ impl WatchdogHandle { | |||
| 170 | /// prevent a reset from occurring. | 168 | /// prevent a reset from occurring. |
| 171 | #[inline] | 169 | #[inline] |
| 172 | pub fn pet(&mut self) { | 170 | pub fn pet(&mut self) { |
| 173 | let r = unsafe { &*WDT::ptr() }; | 171 | let r = crate::pac::WDT; |
| 174 | r.rr[self.index as usize].write(|w| w.rr().reload()); | 172 | r.rr(self.index as usize).write(|w| w.set_rr(vals::Rr::RELOAD)); |
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | /// Has this handle been pet within the current window? | 175 | /// Has this handle been pet within the current window? |
| 178 | pub fn is_pet(&self) -> bool { | 176 | pub fn is_pet(&self) -> bool { |
| 179 | let r = unsafe { &*WDT::ptr() }; | 177 | let r = crate::pac::WDT; |
| 180 | let rd = r.reqstatus.read().bits(); | 178 | !r.reqstatus().read().rr(self.index as usize) |
| 181 | let idx = self.index as usize; | ||
| 182 | ((rd >> idx) & 0x1) == 0 | ||
| 183 | } | 179 | } |
| 184 | 180 | ||
| 185 | /// Steal a watchdog handle by index. | 181 | /// Steal a watchdog handle by index. |
diff --git a/examples/boot/bootloader/nrf/src/main.rs b/examples/boot/bootloader/nrf/src/main.rs index 67c700437..b849a0df3 100644 --- a/examples/boot/bootloader/nrf/src/main.rs +++ b/examples/boot/bootloader/nrf/src/main.rs | |||
| @@ -8,7 +8,7 @@ use cortex_m_rt::{entry, exception}; | |||
| 8 | use defmt_rtt as _; | 8 | use defmt_rtt as _; |
| 9 | use embassy_boot_nrf::*; | 9 | use embassy_boot_nrf::*; |
| 10 | use embassy_nrf::nvmc::Nvmc; | 10 | use embassy_nrf::nvmc::Nvmc; |
| 11 | use embassy_nrf::wdt; | 11 | use embassy_nrf::wdt::{self, HaltConfig, SleepConfig}; |
| 12 | use embassy_sync::blocking_mutex::Mutex; | 12 | use embassy_sync::blocking_mutex::Mutex; |
| 13 | 13 | ||
| 14 | #[entry] | 14 | #[entry] |
| @@ -25,8 +25,8 @@ fn main() -> ! { | |||
| 25 | 25 | ||
| 26 | let mut wdt_config = wdt::Config::default(); | 26 | let mut wdt_config = wdt::Config::default(); |
| 27 | wdt_config.timeout_ticks = 32768 * 5; // timeout seconds | 27 | wdt_config.timeout_ticks = 32768 * 5; // timeout seconds |
| 28 | wdt_config.run_during_sleep = true; | 28 | wdt_config.action_during_sleep = SleepConfig::RUN; |
| 29 | wdt_config.run_during_debug_halt = false; | 29 | wdt_config.action_during_debug_halt = HaltConfig::PAUSE; |
| 30 | 30 | ||
| 31 | let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config); | 31 | let flash = WatchdogFlash::start(Nvmc::new(p.NVMC), p.WDT, wdt_config); |
| 32 | let flash = Mutex::new(RefCell::new(flash)); | 32 | let flash = Mutex::new(RefCell::new(flash)); |
diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index b07adac1f..82364ded8 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::mem; | ||
| 5 | |||
| 6 | use defmt::*; | 4 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 8 | use embassy_net::tcp::TcpSocket; | 6 | use embassy_net::tcp::TcpSocket; |
| @@ -46,11 +44,10 @@ async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static, MTU>> | |||
| 46 | #[embassy_executor::main] | 44 | #[embassy_executor::main] |
| 47 | async fn main(spawner: Spawner) { | 45 | async fn main(spawner: Spawner) { |
| 48 | let p = embassy_nrf::init(Default::default()); | 46 | let p = embassy_nrf::init(Default::default()); |
| 49 | let clock: pac::CLOCK = unsafe { mem::transmute(()) }; | ||
| 50 | 47 | ||
| 51 | info!("Enabling ext hfosc..."); | 48 | info!("Enabling ext hfosc..."); |
| 52 | clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 49 | pac::CLOCK.tasks_hfclkstart().write_value(1); |
| 53 | while clock.events_hfclkstarted.read().bits() != 1 {} | 50 | while pac::CLOCK.events_hfclkstarted().read() != 1 {} |
| 54 | 51 | ||
| 55 | // Create the driver, from the HAL. | 52 | // Create the driver, from the HAL. |
| 56 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); | 53 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); |
diff --git a/examples/nrf52840/src/bin/usb_hid_keyboard.rs b/examples/nrf52840/src/bin/usb_hid_keyboard.rs index e33ee5866..3b752fd16 100644 --- a/examples/nrf52840/src/bin/usb_hid_keyboard.rs +++ b/examples/nrf52840/src/bin/usb_hid_keyboard.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::mem; | ||
| 5 | use core::sync::atomic::{AtomicBool, Ordering}; | 4 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 6 | 5 | ||
| 7 | use defmt::*; | 6 | use defmt::*; |
| @@ -30,11 +29,10 @@ static SUSPENDED: AtomicBool = AtomicBool::new(false); | |||
| 30 | #[embassy_executor::main] | 29 | #[embassy_executor::main] |
| 31 | async fn main(_spawner: Spawner) { | 30 | async fn main(_spawner: Spawner) { |
| 32 | let p = embassy_nrf::init(Default::default()); | 31 | let p = embassy_nrf::init(Default::default()); |
| 33 | let clock: pac::CLOCK = unsafe { mem::transmute(()) }; | ||
| 34 | 32 | ||
| 35 | info!("Enabling ext hfosc..."); | 33 | info!("Enabling ext hfosc..."); |
| 36 | clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 34 | pac::CLOCK.tasks_hfclkstart().write_value(1); |
| 37 | while clock.events_hfclkstarted.read().bits() != 1 {} | 35 | while pac::CLOCK.events_hfclkstarted().read() != 1 {} |
| 38 | 36 | ||
| 39 | // Create the driver, from the HAL. | 37 | // Create the driver, from the HAL. |
| 40 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); | 38 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); |
diff --git a/examples/nrf52840/src/bin/usb_hid_mouse.rs b/examples/nrf52840/src/bin/usb_hid_mouse.rs index 8076ac283..3f13a014e 100644 --- a/examples/nrf52840/src/bin/usb_hid_mouse.rs +++ b/examples/nrf52840/src/bin/usb_hid_mouse.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::mem; | ||
| 5 | |||
| 6 | use defmt::*; | 4 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| @@ -24,11 +22,10 @@ bind_interrupts!(struct Irqs { | |||
| 24 | #[embassy_executor::main] | 22 | #[embassy_executor::main] |
| 25 | async fn main(_spawner: Spawner) { | 23 | async fn main(_spawner: Spawner) { |
| 26 | let p = embassy_nrf::init(Default::default()); | 24 | let p = embassy_nrf::init(Default::default()); |
| 27 | let clock: pac::CLOCK = unsafe { mem::transmute(()) }; | ||
| 28 | 25 | ||
| 29 | info!("Enabling ext hfosc..."); | 26 | info!("Enabling ext hfosc..."); |
| 30 | clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 27 | pac::CLOCK.tasks_hfclkstart().write_value(1); |
| 31 | while clock.events_hfclkstarted.read().bits() != 1 {} | 28 | while pac::CLOCK.events_hfclkstarted().read() != 1 {} |
| 32 | 29 | ||
| 33 | // Create the driver, from the HAL. | 30 | // Create the driver, from the HAL. |
| 34 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); | 31 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); |
diff --git a/examples/nrf52840/src/bin/usb_serial.rs b/examples/nrf52840/src/bin/usb_serial.rs index 02048e692..30fe103ad 100644 --- a/examples/nrf52840/src/bin/usb_serial.rs +++ b/examples/nrf52840/src/bin/usb_serial.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::mem; | ||
| 5 | |||
| 6 | use defmt::{info, panic}; | 4 | use defmt::{info, panic}; |
| 7 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| @@ -22,11 +20,10 @@ bind_interrupts!(struct Irqs { | |||
| 22 | #[embassy_executor::main] | 20 | #[embassy_executor::main] |
| 23 | async fn main(_spawner: Spawner) { | 21 | async fn main(_spawner: Spawner) { |
| 24 | let p = embassy_nrf::init(Default::default()); | 22 | let p = embassy_nrf::init(Default::default()); |
| 25 | let clock: pac::CLOCK = unsafe { mem::transmute(()) }; | ||
| 26 | 23 | ||
| 27 | info!("Enabling ext hfosc..."); | 24 | info!("Enabling ext hfosc..."); |
| 28 | clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 25 | pac::CLOCK.tasks_hfclkstart().write_value(1); |
| 29 | while clock.events_hfclkstarted.read().bits() != 1 {} | 26 | while pac::CLOCK.events_hfclkstarted().read() != 1 {} |
| 30 | 27 | ||
| 31 | // Create the driver, from the HAL. | 28 | // Create the driver, from the HAL. |
| 32 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); | 29 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); |
diff --git a/examples/nrf52840/src/bin/usb_serial_multitask.rs b/examples/nrf52840/src/bin/usb_serial_multitask.rs index 895cca8b9..05b5f0ec9 100644 --- a/examples/nrf52840/src/bin/usb_serial_multitask.rs +++ b/examples/nrf52840/src/bin/usb_serial_multitask.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::mem; | ||
| 5 | |||
| 6 | use defmt::{info, panic, unwrap}; | 4 | use defmt::{info, panic, unwrap}; |
| 7 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; | 6 | use embassy_nrf::usb::vbus_detect::HardwareVbusDetect; |
| @@ -39,11 +37,10 @@ async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) { | |||
| 39 | #[embassy_executor::main] | 37 | #[embassy_executor::main] |
| 40 | async fn main(spawner: Spawner) { | 38 | async fn main(spawner: Spawner) { |
| 41 | let p = embassy_nrf::init(Default::default()); | 39 | let p = embassy_nrf::init(Default::default()); |
| 42 | let clock: pac::CLOCK = unsafe { mem::transmute(()) }; | ||
| 43 | 40 | ||
| 44 | info!("Enabling ext hfosc..."); | 41 | info!("Enabling ext hfosc..."); |
| 45 | clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 42 | pac::CLOCK.tasks_hfclkstart().write_value(1); |
| 46 | while clock.events_hfclkstarted.read().bits() != 1 {} | 43 | while pac::CLOCK.events_hfclkstarted().read() != 1 {} |
| 47 | 44 | ||
| 48 | // Create the driver, from the HAL. | 45 | // Create the driver, from the HAL. |
| 49 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); | 46 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); |
diff --git a/examples/nrf52840/src/bin/usb_serial_winusb.rs b/examples/nrf52840/src/bin/usb_serial_winusb.rs index c6675a3d3..7c07158e0 100644 --- a/examples/nrf52840/src/bin/usb_serial_winusb.rs +++ b/examples/nrf52840/src/bin/usb_serial_winusb.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use core::mem; | ||
| 5 | |||
| 6 | use defmt::{info, panic}; | 4 | use defmt::{info, panic}; |
| 7 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| @@ -27,11 +25,10 @@ const DEVICE_INTERFACE_GUIDS: &[&str] = &["{EAA9A5DC-30BA-44BC-9232-606CDC875321 | |||
| 27 | #[embassy_executor::main] | 25 | #[embassy_executor::main] |
| 28 | async fn main(_spawner: Spawner) { | 26 | async fn main(_spawner: Spawner) { |
| 29 | let p = embassy_nrf::init(Default::default()); | 27 | let p = embassy_nrf::init(Default::default()); |
| 30 | let clock: pac::CLOCK = unsafe { mem::transmute(()) }; | ||
| 31 | 28 | ||
| 32 | info!("Enabling ext hfosc..."); | 29 | info!("Enabling ext hfosc..."); |
| 33 | clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); | 30 | pac::CLOCK.tasks_hfclkstart().write_value(1); |
| 34 | while clock.events_hfclkstarted.read().bits() != 1 {} | 31 | while pac::CLOCK.events_hfclkstarted().read() != 1 {} |
| 35 | 32 | ||
| 36 | // Create the driver, from the HAL. | 33 | // Create the driver, from the HAL. |
| 37 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); | 34 | let driver = Driver::new(p.USBD, Irqs, HardwareVbusDetect::new(Irqs)); |
diff --git a/examples/nrf52840/src/bin/wdt.rs b/examples/nrf52840/src/bin/wdt.rs index ede88cc26..0d9ee3cf8 100644 --- a/examples/nrf52840/src/bin/wdt.rs +++ b/examples/nrf52840/src/bin/wdt.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{Input, Pull}; | 6 | use embassy_nrf::gpio::{Input, Pull}; |
| 7 | use embassy_nrf::wdt::{Config, Watchdog}; | 7 | use embassy_nrf::wdt::{Config, HaltConfig, Watchdog}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| 10 | #[embassy_executor::main] | 10 | #[embassy_executor::main] |
| @@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) { | |||
| 17 | 17 | ||
| 18 | // This is needed for `probe-rs run` to be able to catch the panic message | 18 | // This is needed for `probe-rs run` to be able to catch the panic message |
| 19 | // in the WDT interrupt. The core resets 2 ticks after firing the interrupt. | 19 | // in the WDT interrupt. The core resets 2 ticks after firing the interrupt. |
| 20 | config.run_during_debug_halt = false; | 20 | config.action_during_debug_halt = HaltConfig::PAUSE; |
| 21 | 21 | ||
| 22 | let (_wdt, [mut handle]) = match Watchdog::try_new(p.WDT, config) { | 22 | let (_wdt, [mut handle]) = match Watchdog::try_new(p.WDT, config) { |
| 23 | Ok(x) => x, | 23 | Ok(x) => x, |
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index d36ab9c67..6a710f29d 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml | |||
| @@ -87,6 +87,11 @@ path = "src/bin/gpiote.rs" | |||
| 87 | required-features = [] | 87 | required-features = [] |
| 88 | 88 | ||
| 89 | [[bin]] | 89 | [[bin]] |
| 90 | name = "spim" | ||
| 91 | path = "src/bin/spim.rs" | ||
| 92 | required-features = [ "easydma",] | ||
| 93 | |||
| 94 | [[bin]] | ||
| 90 | name = "timer" | 95 | name = "timer" |
| 91 | path = "src/bin/timer.rs" | 96 | path = "src/bin/timer.rs" |
| 92 | required-features = [] | 97 | required-features = [] |
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 45daaae0c..cf9ca50d2 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs | |||
| @@ -50,15 +50,15 @@ async fn main(_spawner: Spawner) { | |||
| 50 | const NSPAM: usize = 17; | 50 | const NSPAM: usize = 17; |
| 51 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | 51 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 52 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); | 52 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); |
| 53 | let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; | 53 | let spam_peri = pac::UARTE1; |
| 54 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; | 54 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_endtx().as_ptr())) }; |
| 55 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; | 55 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_starttx().as_ptr())) }; |
| 56 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); | 56 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); |
| 57 | spam_ppi.enable(); | 57 | spam_ppi.enable(); |
| 58 | let p = (&raw mut TX_BUF) as *mut u8; | 58 | let p = (&raw mut TX_BUF) as *mut u8; |
| 59 | spam_peri.txd.ptr.write(|w| unsafe { w.ptr().bits(p as u32) }); | 59 | spam_peri.txd().ptr().write_value(p as u32); |
| 60 | spam_peri.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(NSPAM as _) }); | 60 | spam_peri.txd().maxcnt().write(|w| w.set_maxcnt(NSPAM as _)); |
| 61 | spam_peri.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 61 | spam_peri.tasks_starttx().write_value(1); |
| 62 | 62 | ||
| 63 | let mut i = 0; | 63 | let mut i = 0; |
| 64 | let mut total = 0; | 64 | let mut total = 0; |
diff --git a/tests/nrf/src/bin/gpio.rs b/tests/nrf/src/bin/gpio.rs index 9e809a694..4995d244c 100644 --- a/tests/nrf/src/bin/gpio.rs +++ b/tests/nrf/src/bin/gpio.rs | |||
| @@ -17,10 +17,12 @@ async fn main(_spawner: Spawner) { | |||
| 17 | let mut output = Output::new(peri!(p, PIN_B), Level::Low, OutputDrive::Standard); | 17 | let mut output = Output::new(peri!(p, PIN_B), Level::Low, OutputDrive::Standard); |
| 18 | 18 | ||
| 19 | output.set_low(); | 19 | output.set_low(); |
| 20 | assert!(output.is_set_low()); | ||
| 20 | Timer::after_millis(10).await; | 21 | Timer::after_millis(10).await; |
| 21 | assert!(input.is_low()); | 22 | assert!(input.is_low()); |
| 22 | 23 | ||
| 23 | output.set_high(); | 24 | output.set_high(); |
| 25 | assert!(output.is_set_high()); | ||
| 24 | Timer::after_millis(10).await; | 26 | Timer::after_millis(10).await; |
| 25 | assert!(input.is_high()); | 27 | assert!(input.is_high()); |
| 26 | 28 | ||
diff --git a/tests/nrf/src/bin/spim.rs b/tests/nrf/src/bin/spim.rs new file mode 100644 index 000000000..c2ec90b88 --- /dev/null +++ b/tests/nrf/src/bin/spim.rs | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // required-features: easydma | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_nrf::spim::Spim; | ||
| 11 | use embassy_nrf::{peripherals, spim}; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | #[embassy_executor::main] | ||
| 15 | async fn main(_spawner: Spawner) { | ||
| 16 | let mut p = embassy_nrf::init(Default::default()); | ||
| 17 | let mut config = spim::Config::default(); | ||
| 18 | config.frequency = spim::Frequency::M1; | ||
| 19 | let mut spim = Spim::new( | ||
| 20 | &mut peri!(p, SPIM0), | ||
| 21 | irqs!(SPIM0), | ||
| 22 | &mut peri!(p, PIN_X), | ||
| 23 | &mut peri!(p, PIN_A), // MISO | ||
| 24 | &mut peri!(p, PIN_B), // MOSI | ||
| 25 | config.clone(), | ||
| 26 | ); | ||
| 27 | let data = [ | ||
| 28 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 29 | ]; | ||
| 30 | let mut buf = [0u8; 16]; | ||
| 31 | |||
| 32 | buf.fill(0); | ||
| 33 | spim.blocking_transfer(&mut buf, &data).unwrap(); | ||
| 34 | assert_eq!(data, buf); | ||
| 35 | |||
| 36 | buf.fill(0); | ||
| 37 | spim.transfer(&mut buf, &data).await.unwrap(); | ||
| 38 | assert_eq!(data, buf); | ||
| 39 | |||
| 40 | info!("Test OK"); | ||
| 41 | cortex_m::asm::bkpt(); | ||
| 42 | } | ||
diff --git a/tests/nrf/src/common.rs b/tests/nrf/src/common.rs index ff5299b0f..c588dabf5 100644 --- a/tests/nrf/src/common.rs +++ b/tests/nrf/src/common.rs | |||
| @@ -52,51 +52,66 @@ define_peris!(PIN_A = P0_13, PIN_B = P0_14,); | |||
| 52 | #[cfg(feature = "nrf52832")] | 52 | #[cfg(feature = "nrf52832")] |
| 53 | define_peris!( | 53 | define_peris!( |
| 54 | PIN_A = P0_11, PIN_B = P0_12, | 54 | PIN_A = P0_11, PIN_B = P0_12, |
| 55 | PIN_X = P0_13, | ||
| 55 | UART0 = UARTE0, | 56 | UART0 = UARTE0, |
| 57 | SPIM0 = TWISPI0, | ||
| 56 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | 58 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, |
| 57 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | 59 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, |
| 60 | @irq SPIM0 = {SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => spim::InterruptHandler<peripherals::TWISPI0>;}, | ||
| 58 | ); | 61 | ); |
| 59 | 62 | ||
| 60 | #[cfg(feature = "nrf52833")] | 63 | #[cfg(feature = "nrf52833")] |
| 61 | define_peris!( | 64 | define_peris!( |
| 62 | PIN_A = P1_01, PIN_B = P1_02, | 65 | PIN_A = P1_01, PIN_B = P1_02, |
| 66 | PIN_X = P1_03, | ||
| 63 | UART0 = UARTE0, | 67 | UART0 = UARTE0, |
| 64 | UART1 = UARTE1, | 68 | UART1 = UARTE1, |
| 69 | SPIM0 = TWISPI0, | ||
| 65 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | 70 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, |
| 66 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | 71 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, |
| 67 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | 72 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, |
| 68 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | 73 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, |
| 74 | @irq SPIM0 = {SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => spim::InterruptHandler<peripherals::TWISPI0>;}, | ||
| 69 | ); | 75 | ); |
| 70 | 76 | ||
| 71 | #[cfg(feature = "nrf52840")] | 77 | #[cfg(feature = "nrf52840")] |
| 72 | define_peris!( | 78 | define_peris!( |
| 73 | PIN_A = P1_02, PIN_B = P1_03, | 79 | PIN_A = P1_02, PIN_B = P1_03, |
| 80 | PIN_X = P1_04, | ||
| 74 | UART0 = UARTE0, | 81 | UART0 = UARTE0, |
| 75 | UART1 = UARTE1, | 82 | UART1 = UARTE1, |
| 83 | SPIM0 = TWISPI0, | ||
| 76 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | 84 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, |
| 77 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | 85 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, |
| 78 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | 86 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, |
| 79 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | 87 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, |
| 88 | @irq SPIM0 = {SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => spim::InterruptHandler<peripherals::TWISPI0>;}, | ||
| 80 | ); | 89 | ); |
| 81 | 90 | ||
| 82 | #[cfg(feature = "nrf5340")] | 91 | #[cfg(feature = "nrf5340")] |
| 83 | define_peris!( | 92 | define_peris!( |
| 84 | PIN_A = P1_08, PIN_B = P1_09, | 93 | PIN_A = P1_08, PIN_B = P1_09, |
| 94 | PIN_X = P1_10, | ||
| 85 | UART0 = SERIAL0, | 95 | UART0 = SERIAL0, |
| 86 | UART1 = SERIAL1, | 96 | UART1 = SERIAL1, |
| 97 | SPIM0 = SERIAL0, | ||
| 87 | @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | 98 | @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, |
| 88 | @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | 99 | @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, |
| 89 | @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | 100 | @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, |
| 90 | @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | 101 | @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, |
| 102 | @irq SPIM0 = {SERIAL0 => spim::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 91 | ); | 103 | ); |
| 92 | 104 | ||
| 93 | #[cfg(feature = "nrf9160")] | 105 | #[cfg(feature = "nrf9160")] |
| 94 | define_peris!( | 106 | define_peris!( |
| 95 | PIN_A = P0_00, PIN_B = P0_01, | 107 | PIN_A = P0_00, PIN_B = P0_01, |
| 108 | PIN_X = P0_02, | ||
| 96 | UART0 = SERIAL0, | 109 | UART0 = SERIAL0, |
| 97 | UART1 = SERIAL1, | 110 | UART1 = SERIAL1, |
| 111 | SPIM0 = SERIAL0, | ||
| 98 | @irq UART0 = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | 112 | @irq UART0 = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, |
| 99 | @irq UART1 = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | 113 | @irq UART1 = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, |
| 100 | @irq UART0_BUFFERED = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | 114 | @irq UART0_BUFFERED = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, |
| 101 | @irq UART1_BUFFERED = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | 115 | @irq UART1_BUFFERED = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, |
| 116 | @irq SPIM0 = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => spim::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 102 | ); | 117 | ); |
