diff options
49 files changed, 2831 insertions, 726 deletions
diff --git a/embassy-net-nrf91/CHANGELOG.md b/embassy-net-nrf91/CHANGELOG.md index 52cbf5ef3..11974ac04 100644 --- a/embassy-net-nrf91/CHANGELOG.md +++ b/embassy-net-nrf91/CHANGELOG.md | |||
| @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - changed: updated to nrf-pac with nrf52/nrf53/nrf91 register layout more similar to nrf54 | ||
| 12 | |||
| 11 | ## 0.1.1 - 2025-08-14 | 13 | ## 0.1.1 - 2025-08-14 |
| 12 | 14 | ||
| 13 | - First release with changelog. | 15 | - First release with changelog. |
diff --git a/embassy-net-nrf91/Cargo.toml b/embassy-net-nrf91/Cargo.toml index ecb10246a..75b7aeeb2 100644 --- a/embassy-net-nrf91/Cargo.toml +++ b/embassy-net-nrf91/Cargo.toml | |||
| @@ -18,7 +18,7 @@ log = ["dep:log"] | |||
| 18 | defmt = { version = "1.0.1", optional = true } | 18 | defmt = { version = "1.0.1", optional = true } |
| 19 | log = { version = "0.4.14", optional = true } | 19 | log = { version = "0.4.14", optional = true } |
| 20 | 20 | ||
| 21 | nrf-pac = "0.1.0" | 21 | nrf-pac = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "58198c23bce72edc10b4e1656d1b54441fc74e7c" } |
| 22 | cortex-m = "0.7.7" | 22 | cortex-m = "0.7.7" |
| 23 | 23 | ||
| 24 | embassy-time = { version = "0.5.0", path = "../embassy-time" } | 24 | embassy-time = { version = "0.5.0", path = "../embassy-time" } |
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md index 89adaf2da..c23613f19 100644 --- a/embassy-nrf/CHANGELOG.md +++ b/embassy-nrf/CHANGELOG.md | |||
| @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 17 | - changed: allow configuring the PWM peripheral in the constructor of `SimplePwm` | 17 | - changed: allow configuring the PWM peripheral in the constructor of `SimplePwm` |
| 18 | - changed: support setting duty cycles with inverted polarity in `SimplePwm` | 18 | - changed: support setting duty cycles with inverted polarity in `SimplePwm` |
| 19 | - added: support setting the duty cycles of all channels at once in `SimplePwm` | 19 | - added: support setting the duty cycles of all channels at once in `SimplePwm` |
| 20 | - changed: updated to nrf-pac with nrf52/nrf53/nrf91 register layout more similar to nrf54 | ||
| 21 | - added: support for nrf54l peripherals: uart, gpiote, twim, twis, spim, spis, dppi, pwm, saadc | ||
| 20 | 22 | ||
| 21 | ## 0.8.0 - 2025-09-30 | 23 | ## 0.8.0 - 2025-09-30 |
| 22 | 24 | ||
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 28f137d5c..08f4b280b 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml | |||
| @@ -104,17 +104,17 @@ qspi-multiwrite-flash = [] | |||
| 104 | 104 | ||
| 105 | #! ### Chip selection features | 105 | #! ### Chip selection features |
| 106 | ## nRF51 | 106 | ## nRF51 |
| 107 | nrf51 = ["nrf-pac/nrf51", "_nrf51"] | 107 | nrf51 = ["nrf-pac/nrf51", "_nrf51", "_spi-v1"] |
| 108 | ## nRF52805 | 108 | ## nRF52805 |
| 109 | nrf52805 = ["nrf-pac/nrf52805", "_nrf52"] | 109 | nrf52805 = ["nrf-pac/nrf52805", "_nrf52", "_spi-v1"] |
| 110 | ## nRF52810 | 110 | ## nRF52810 |
| 111 | nrf52810 = ["nrf-pac/nrf52810", "_nrf52"] | 111 | nrf52810 = ["nrf-pac/nrf52810", "_nrf52", "_spi-v1"] |
| 112 | ## nRF52811 | 112 | ## nRF52811 |
| 113 | nrf52811 = ["nrf-pac/nrf52811", "_nrf52"] | 113 | nrf52811 = ["nrf-pac/nrf52811", "_nrf52", "_spi-v1"] |
| 114 | ## nRF52820 | 114 | ## nRF52820 |
| 115 | nrf52820 = ["nrf-pac/nrf52820", "_nrf52"] | 115 | nrf52820 = ["nrf-pac/nrf52820", "_nrf52", "_spi-v1"] |
| 116 | ## nRF52832 | 116 | ## nRF52832 |
| 117 | nrf52832 = ["nrf-pac/nrf52832", "_nrf52", "_nrf52832_anomaly_109"] | 117 | nrf52832 = ["nrf-pac/nrf52832", "_nrf52", "_nrf52832_anomaly_109", "_spi-v1"] |
| 118 | ## nRF52833 | 118 | ## nRF52833 |
| 119 | nrf52833 = ["nrf-pac/nrf52833", "_nrf52", "_gpio-p1"] | 119 | nrf52833 = ["nrf-pac/nrf52833", "_nrf52", "_gpio-p1"] |
| 120 | ## nRF52840 | 120 | ## nRF52840 |
| @@ -154,10 +154,10 @@ _nrf54l15-app = ["_nrf54l15", "nrf-pac/nrf54l15-app"] | |||
| 154 | _nrf54l15 = ["_nrf54l", "_gpio-p1", "_gpio-p2"] | 154 | _nrf54l15 = ["_nrf54l", "_gpio-p1", "_gpio-p2"] |
| 155 | _nrf54l = ["_dppi"] | 155 | _nrf54l = ["_dppi"] |
| 156 | 156 | ||
| 157 | _nrf9160 = ["nrf-pac/nrf9160", "_dppi"] | 157 | _nrf9160 = ["nrf-pac/nrf9160", "_dppi", "_spi-v1"] |
| 158 | _nrf9120 = ["nrf-pac/nrf9120", "_dppi"] | 158 | _nrf9120 = ["nrf-pac/nrf9120", "_dppi", "_spi-v1"] |
| 159 | _nrf52 = ["_ppi"] | 159 | _nrf52 = ["_ppi"] |
| 160 | _nrf51 = ["_ppi"] | 160 | _nrf51 = ["_ppi", "_spi-v1"] |
| 161 | _nrf91 = [] | 161 | _nrf91 = [] |
| 162 | 162 | ||
| 163 | _time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-32_768", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] | 163 | _time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-32_768", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] |
| @@ -172,6 +172,7 @@ _ppi = [] | |||
| 172 | _dppi = [] | 172 | _dppi = [] |
| 173 | _gpio-p1 = [] | 173 | _gpio-p1 = [] |
| 174 | _gpio-p2 = [] | 174 | _gpio-p2 = [] |
| 175 | _spi-v1 = [] | ||
| 175 | 176 | ||
| 176 | # Errata workarounds | 177 | # Errata workarounds |
| 177 | _nrf52832_anomaly_109 = [] | 178 | _nrf52832_anomaly_109 = [] |
| @@ -199,7 +200,7 @@ embedded-io-async = { version = "0.6.1" } | |||
| 199 | rand-core-06 = { package = "rand_core", version = "0.6" } | 200 | rand-core-06 = { package = "rand_core", version = "0.6" } |
| 200 | rand-core-09 = { package = "rand_core", version = "0.9" } | 201 | rand-core-09 = { package = "rand_core", version = "0.9" } |
| 201 | 202 | ||
| 202 | nrf-pac = "0.1.0" | 203 | nrf-pac = { version = "0.1.0", git = "https://github.com/embassy-rs/nrf-pac.git", rev = "58198c23bce72edc10b4e1656d1b54441fc74e7c" } |
| 203 | 204 | ||
| 204 | defmt = { version = "1.0.1", optional = true } | 205 | defmt = { version = "1.0.1", optional = true } |
| 205 | bitflags = "2.4.2" | 206 | bitflags = "2.4.2" |
diff --git a/embassy-nrf/src/buffered_uarte/mod.rs b/embassy-nrf/src/buffered_uarte/mod.rs new file mode 100644 index 000000000..75d84baac --- /dev/null +++ b/embassy-nrf/src/buffered_uarte/mod.rs | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | //! Async buffered UART driver. | ||
| 2 | //! | ||
| 3 | //! Note that discarding a future from a read or write operation may lead to losing | ||
| 4 | //! data. For example, when using `futures_util::future::select` and completion occurs | ||
| 5 | //! on the "other" future, you should capture the incomplete future and continue to use | ||
| 6 | //! it for the next read or write. This pattern is a consideration for all IO, and not | ||
| 7 | //! just serial communications. | ||
| 8 | //! | ||
| 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. | ||
| 10 | #[cfg_attr(not(feature = "_nrf54l"), path = "v1.rs")] | ||
| 11 | #[cfg_attr(feature = "_nrf54l", path = "v2.rs")] | ||
| 12 | mod _version; | ||
| 13 | |||
| 14 | pub use _version::*; | ||
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte/v1.rs index b1eb5c81a..07de22717 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte/v1.rs | |||
| @@ -102,25 +102,25 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 102 | ss.rx_waker.wake(); | 102 | ss.rx_waker.wake(); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | if r.events_endrx().read() != 0 { | 105 | if r.events_dma().rx().end().read() != 0 { |
| 106 | //trace!(" irq_rx: endrx"); | 106 | //trace!(" irq_rx: endrx"); |
| 107 | r.events_endrx().write_value(0); | 107 | r.events_dma().rx().end().write_value(0); |
| 108 | 108 | ||
| 109 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 109 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 110 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 110 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | if r.events_rxstarted().read() != 0 || !s.rx_started.load(Ordering::Relaxed) { | 113 | if r.events_dma().rx().ready().read() != 0 || !s.rx_started.load(Ordering::Relaxed) { |
| 114 | //trace!(" irq_rx: rxstarted"); | 114 | //trace!(" irq_rx: rxstarted"); |
| 115 | let (ptr, len) = rx.push_buf(); | 115 | let (ptr, len) = rx.push_buf(); |
| 116 | if len >= half_len { | 116 | if len >= half_len { |
| 117 | r.events_rxstarted().write_value(0); | 117 | r.events_dma().rx().ready().write_value(0); |
| 118 | 118 | ||
| 119 | //trace!(" irq_rx: starting second {:?}", half_len); | 119 | //trace!(" irq_rx: starting second {:?}", half_len); |
| 120 | 120 | ||
| 121 | // Set up the DMA read | 121 | // Set up the DMA read |
| 122 | r.rxd().ptr().write_value(ptr as u32); | 122 | r.dma().rx().ptr().write_value(ptr as u32); |
| 123 | r.rxd().maxcnt().write(|w| w.set_maxcnt(half_len as _)); | 123 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(half_len as _)); |
| 124 | 124 | ||
| 125 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); | 125 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); |
| 126 | 126 | ||
| @@ -133,9 +133,9 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 133 | // and manually start. | 133 | // and manually start. |
| 134 | 134 | ||
| 135 | // check again in case endrx has happened between the last check and now. | 135 | // check again in case endrx has happened between the last check and now. |
| 136 | if r.events_endrx().read() != 0 { | 136 | if r.events_dma().rx().end().read() != 0 { |
| 137 | //trace!(" irq_rx: endrx"); | 137 | //trace!(" irq_rx: endrx"); |
| 138 | r.events_endrx().write_value(0); | 138 | r.events_dma().rx().end().write_value(0); |
| 139 | 139 | ||
| 140 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 140 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 141 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 141 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| @@ -161,7 +161,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 161 | ppi::regs().chenclr().write(|w| w.set_ch(chn as _, true)); | 161 | ppi::regs().chenclr().write(|w| w.set_ch(chn as _, true)); |
| 162 | 162 | ||
| 163 | // manually start | 163 | // manually start |
| 164 | r.tasks_startrx().write_value(1); | 164 | r.tasks_dma().rx().start().write_value(1); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | rx.push_done(half_len); | 167 | rx.push_done(half_len); |
| @@ -170,7 +170,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 170 | s.rx_started.store(true, Ordering::Relaxed); | 170 | s.rx_started.store(true, Ordering::Relaxed); |
| 171 | } else { | 171 | } else { |
| 172 | //trace!(" irq_rx: rxstarted no buf"); | 172 | //trace!(" irq_rx: rxstarted no buf"); |
| 173 | r.intenclr().write(|w| w.set_rxstarted(true)); | 173 | r.intenclr().write(|w| w.set_dmarxready(true)); |
| 174 | } | 174 | } |
| 175 | } | 175 | } |
| 176 | } | 176 | } |
| @@ -179,8 +179,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 179 | 179 | ||
| 180 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { | 180 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { |
| 181 | // TX end | 181 | // TX end |
| 182 | if r.events_endtx().read() != 0 { | 182 | if r.events_dma().tx().end().read() != 0 { |
| 183 | r.events_endtx().write_value(0); | 183 | r.events_dma().tx().end().write_value(0); |
| 184 | 184 | ||
| 185 | let n = s.tx_count.load(Ordering::Relaxed); | 185 | let n = s.tx_count.load(Ordering::Relaxed); |
| 186 | //trace!(" irq_tx: endtx {:?}", n); | 186 | //trace!(" irq_tx: endtx {:?}", n); |
| @@ -198,11 +198,11 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 198 | s.tx_count.store(len, Ordering::Relaxed); | 198 | s.tx_count.store(len, Ordering::Relaxed); |
| 199 | 199 | ||
| 200 | // Set up the DMA write | 200 | // Set up the DMA write |
| 201 | r.txd().ptr().write_value(ptr as u32); | 201 | r.dma().tx().ptr().write_value(ptr as u32); |
| 202 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 202 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 203 | 203 | ||
| 204 | // Start UARTE Transmit transaction | 204 | // Start UARTE Transmit transaction |
| 205 | r.tasks_starttx().write_value(1); | 205 | r.tasks_dma().tx().start().write_value(1); |
| 206 | } | 206 | } |
| 207 | } | 207 | } |
| 208 | } | 208 | } |
| @@ -456,11 +456,11 @@ impl<'d> BufferedUarteTx<'d> { | |||
| 456 | let len = tx_buffer.len(); | 456 | let len = tx_buffer.len(); |
| 457 | unsafe { buffered_state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | 457 | unsafe { buffered_state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; |
| 458 | 458 | ||
| 459 | r.events_txstarted().write_value(0); | 459 | r.events_dma().tx().ready().write_value(0); |
| 460 | 460 | ||
| 461 | // Enable interrupts | 461 | // Enable interrupts |
| 462 | r.intenset().write(|w| { | 462 | r.intenset().write(|w| { |
| 463 | w.set_endtx(true); | 463 | w.set_dmatxend(true); |
| 464 | }); | 464 | }); |
| 465 | 465 | ||
| 466 | Self { | 466 | Self { |
| @@ -551,11 +551,11 @@ impl<'a> Drop for BufferedUarteTx<'a> { | |||
| 551 | 551 | ||
| 552 | r.intenclr().write(|w| { | 552 | r.intenclr().write(|w| { |
| 553 | w.set_txdrdy(true); | 553 | w.set_txdrdy(true); |
| 554 | w.set_txstarted(true); | 554 | w.set_dmatxready(true); |
| 555 | w.set_txstopped(true); | 555 | w.set_txstopped(true); |
| 556 | }); | 556 | }); |
| 557 | r.events_txstopped().write_value(0); | 557 | r.events_txstopped().write_value(0); |
| 558 | r.tasks_stoptx().write_value(1); | 558 | r.tasks_dma().tx().stop().write_value(1); |
| 559 | while r.events_txstopped().read() == 0 {} | 559 | while r.events_txstopped().read() == 0 {} |
| 560 | 560 | ||
| 561 | let s = self.buffered_state; | 561 | let s = self.buffered_state; |
| @@ -701,16 +701,16 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 701 | let errors = r.errorsrc().read(); | 701 | let errors = r.errorsrc().read(); |
| 702 | r.errorsrc().write_value(errors); | 702 | r.errorsrc().write_value(errors); |
| 703 | 703 | ||
| 704 | r.events_rxstarted().write_value(0); | 704 | r.events_dma().rx().ready().write_value(0); |
| 705 | r.events_error().write_value(0); | 705 | r.events_error().write_value(0); |
| 706 | r.events_endrx().write_value(0); | 706 | r.events_dma().rx().end().write_value(0); |
| 707 | 707 | ||
| 708 | // Enable interrupts | 708 | // Enable interrupts |
| 709 | r.intenset().write(|w| { | 709 | r.intenset().write(|w| { |
| 710 | w.set_endtx(true); | 710 | w.set_dmatxend(true); |
| 711 | w.set_rxstarted(true); | 711 | w.set_dmarxready(true); |
| 712 | w.set_error(true); | 712 | w.set_error(true); |
| 713 | w.set_endrx(true); | 713 | w.set_dmarxend(true); |
| 714 | }); | 714 | }); |
| 715 | 715 | ||
| 716 | // Configure byte counter. | 716 | // Configure byte counter. |
| @@ -729,8 +729,8 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 729 | let mut ppi_group = PpiGroup::new(ppi_group); | 729 | let mut ppi_group = PpiGroup::new(ppi_group); |
| 730 | let mut ppi_ch2 = Ppi::new_one_to_two( | 730 | let mut ppi_ch2 = Ppi::new_one_to_two( |
| 731 | ppi_ch2, | 731 | ppi_ch2, |
| 732 | Event::from_reg(r.events_endrx()), | 732 | Event::from_reg(r.events_dma().rx().end()), |
| 733 | Task::from_reg(r.tasks_startrx()), | 733 | Task::from_reg(r.tasks_dma().rx().start()), |
| 734 | ppi_group.task_disable_all(), | 734 | ppi_group.task_disable_all(), |
| 735 | ); | 735 | ); |
| 736 | ppi_ch2.disable(); | 736 | ppi_ch2.disable(); |
| @@ -823,7 +823,7 @@ impl<'d> BufferedUarteRx<'d> { | |||
| 823 | let s = self.buffered_state; | 823 | let s = self.buffered_state; |
| 824 | let mut rx = unsafe { s.rx_buf.reader() }; | 824 | let mut rx = unsafe { s.rx_buf.reader() }; |
| 825 | rx.pop_done(amt); | 825 | rx.pop_done(amt); |
| 826 | self.r.intenset().write(|w| w.set_rxstarted(true)); | 826 | self.r.intenset().write(|w| w.set_dmarxready(true)); |
| 827 | } | 827 | } |
| 828 | 828 | ||
| 829 | /// we are ready to read if there is data in the buffer | 829 | /// we are ready to read if there is data in the buffer |
| @@ -846,11 +846,11 @@ impl<'a> Drop for BufferedUarteRx<'a> { | |||
| 846 | 846 | ||
| 847 | r.intenclr().write(|w| { | 847 | r.intenclr().write(|w| { |
| 848 | w.set_rxdrdy(true); | 848 | w.set_rxdrdy(true); |
| 849 | w.set_rxstarted(true); | 849 | w.set_dmarxready(true); |
| 850 | w.set_rxto(true); | 850 | w.set_rxto(true); |
| 851 | }); | 851 | }); |
| 852 | r.events_rxto().write_value(0); | 852 | r.events_rxto().write_value(0); |
| 853 | r.tasks_stoprx().write_value(1); | 853 | r.tasks_dma().rx().stop().write_value(1); |
| 854 | while r.events_rxto().read() == 0 {} | 854 | while r.events_rxto().read() == 0 {} |
| 855 | 855 | ||
| 856 | let s = self.buffered_state; | 856 | let s = self.buffered_state; |
diff --git a/embassy-nrf/src/buffered_uarte/v2.rs b/embassy-nrf/src/buffered_uarte/v2.rs new file mode 100644 index 000000000..d0d2d97d1 --- /dev/null +++ b/embassy-nrf/src/buffered_uarte/v2.rs | |||
| @@ -0,0 +1,687 @@ | |||
| 1 | //! Async buffered UART driver. | ||
| 2 | //! | ||
| 3 | //! Note that discarding a future from a read or write operation may lead to losing | ||
| 4 | //! data. For example, when using `futures_util::future::select` and completion occurs | ||
| 5 | //! on the "other" future, you should capture the incomplete future and continue to use | ||
| 6 | //! it for the next read or write. This pattern is a consideration for all IO, and not | ||
| 7 | //! just serial communications. | ||
| 8 | //! | ||
| 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. | ||
| 10 | //! | ||
| 11 | //! The code is based on the generic buffered_uarte implementation but uses the nrf54l | ||
| 12 | //! frame timeout event to correctly determine the size of transferred data. | ||
| 13 | //! Counting of rxrdy events, used in the generic implementation, cannot be applied | ||
| 14 | //! to nrf54l chips, as they buffer up to 4 bytes in a single DMA transaction. | ||
| 15 | //! The only reliable way to find the number of bytes received is to stop the transfer, | ||
| 16 | //! wait for the DMA stopped event, and read the value in the rx.dma.amount register. | ||
| 17 | //! This also flushes all in-flight data to RAM. | ||
| 18 | |||
| 19 | use core::cmp::min; | ||
| 20 | use core::future::{Future, poll_fn}; | ||
| 21 | use core::marker::PhantomData; | ||
| 22 | use core::slice; | ||
| 23 | use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering, compiler_fence}; | ||
| 24 | use core::task::Poll; | ||
| 25 | |||
| 26 | use embassy_hal_internal::Peri; | ||
| 27 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | ||
| 28 | use pac::uarte::vals; | ||
| 29 | // Re-export SVD variants to allow user to directly set values | ||
| 30 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; | ||
| 31 | |||
| 32 | use crate::gpio::{AnyPin, Pin as GpioPin}; | ||
| 33 | use crate::interrupt::typelevel::Interrupt; | ||
| 34 | use crate::uarte::{Config, Instance as UarteInstance, configure, configure_rx_pins, configure_tx_pins, drop_tx_rx}; | ||
| 35 | use crate::{EASY_DMA_SIZE, interrupt, pac}; | ||
| 36 | |||
| 37 | pub(crate) struct State { | ||
| 38 | tx_buf: RingBuffer, | ||
| 39 | tx_count: AtomicUsize, | ||
| 40 | |||
| 41 | rx_buf: RingBuffer, | ||
| 42 | rx_started: AtomicBool, | ||
| 43 | } | ||
| 44 | |||
| 45 | /// UART error. | ||
| 46 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| 47 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 48 | #[non_exhaustive] | ||
| 49 | pub enum Error { | ||
| 50 | // No errors for now | ||
| 51 | } | ||
| 52 | |||
| 53 | impl State { | ||
| 54 | pub(crate) const fn new() -> Self { | ||
| 55 | Self { | ||
| 56 | tx_buf: RingBuffer::new(), | ||
| 57 | tx_count: AtomicUsize::new(0), | ||
| 58 | |||
| 59 | rx_buf: RingBuffer::new(), | ||
| 60 | rx_started: AtomicBool::new(false), | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | /// Interrupt handler. | ||
| 66 | pub struct InterruptHandler<U: UarteInstance> { | ||
| 67 | _phantom: PhantomData<U>, | ||
| 68 | } | ||
| 69 | |||
| 70 | impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for InterruptHandler<U> { | ||
| 71 | unsafe fn on_interrupt() { | ||
| 72 | info!("irq: start"); | ||
| 73 | let r = U::regs(); | ||
| 74 | let ss = U::state(); | ||
| 75 | let s = U::buffered_state(); | ||
| 76 | |||
| 77 | if let Some(mut rx) = unsafe { s.rx_buf.try_writer() } { | ||
| 78 | let buf_len = s.rx_buf.len(); | ||
| 79 | let half_len = buf_len / 2; | ||
| 80 | |||
| 81 | if r.events_error().read() != 0 { | ||
| 82 | r.events_error().write_value(0); | ||
| 83 | let errs = r.errorsrc().read(); | ||
| 84 | r.errorsrc().write_value(errs); | ||
| 85 | |||
| 86 | if errs.overrun() { | ||
| 87 | panic!("BufferedUarte UART overrun"); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | let first_run = !s.rx_started.swap(true, Ordering::Relaxed); | ||
| 92 | if r.events_dma().rx().end().read() != 0 || first_run { | ||
| 93 | //trace!(" irq_rx: endrx"); | ||
| 94 | r.events_dma().rx().end().write_value(0); | ||
| 95 | |||
| 96 | if !first_run { | ||
| 97 | // Received some bytes, wake task. | ||
| 98 | let rxed = r.dma().rx().amount().read().amount() as usize; | ||
| 99 | rx.push_done(rxed); | ||
| 100 | ss.rx_waker.wake(); | ||
| 101 | } | ||
| 102 | |||
| 103 | let (ptr, len) = rx.push_buf(); | ||
| 104 | if len == 0 { | ||
| 105 | panic!("BufferedUarte buffer overrun"); | ||
| 106 | } | ||
| 107 | |||
| 108 | let len = if len > half_len { half_len } else { len }; | ||
| 109 | |||
| 110 | // Set up the DMA read | ||
| 111 | r.dma().rx().ptr().write_value(ptr as u32); | ||
| 112 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); | ||
| 113 | |||
| 114 | // manually start | ||
| 115 | r.tasks_dma().rx().start().write_value(1); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | // ============================= | ||
| 120 | |||
| 121 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { | ||
| 122 | // TX end | ||
| 123 | if r.events_dma().tx().end().read() != 0 { | ||
| 124 | r.events_dma().tx().end().write_value(0); | ||
| 125 | |||
| 126 | let n = s.tx_count.load(Ordering::Relaxed); | ||
| 127 | //trace!(" irq_tx: endtx {:?}", n); | ||
| 128 | tx.pop_done(n); | ||
| 129 | ss.tx_waker.wake(); | ||
| 130 | s.tx_count.store(0, Ordering::Relaxed); | ||
| 131 | } | ||
| 132 | |||
| 133 | // If not TXing, start. | ||
| 134 | if s.tx_count.load(Ordering::Relaxed) == 0 { | ||
| 135 | let (ptr, len) = tx.pop_buf(); | ||
| 136 | let len = len.min(EASY_DMA_SIZE); | ||
| 137 | if len != 0 { | ||
| 138 | //trace!(" irq_tx: starting {:?}", len); | ||
| 139 | s.tx_count.store(len, Ordering::Relaxed); | ||
| 140 | |||
| 141 | // Set up the DMA write | ||
| 142 | r.dma().tx().ptr().write_value(ptr as u32); | ||
| 143 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); | ||
| 144 | |||
| 145 | // Start UARTE Transmit transaction | ||
| 146 | r.tasks_dma().tx().start().write_value(1); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | //trace!("irq: end"); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | /// Buffered UARTE driver. | ||
| 156 | pub struct BufferedUarte<'d, U: UarteInstance> { | ||
| 157 | tx: BufferedUarteTx<'d, U>, | ||
| 158 | rx: BufferedUarteRx<'d, U>, | ||
| 159 | } | ||
| 160 | |||
| 161 | impl<'d, U: UarteInstance> Unpin for BufferedUarte<'d, U> {} | ||
| 162 | |||
| 163 | impl<'d, U: UarteInstance> BufferedUarte<'d, U> { | ||
| 164 | /// Create a new BufferedUarte without hardware flow control. | ||
| 165 | #[allow(clippy::too_many_arguments)] | ||
| 166 | pub fn new( | ||
| 167 | uarte: Peri<'d, U>, | ||
| 168 | rxd: Peri<'d, impl GpioPin>, | ||
| 169 | txd: Peri<'d, impl GpioPin>, | ||
| 170 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 171 | config: Config, | ||
| 172 | rx_buffer: &'d mut [u8], | ||
| 173 | tx_buffer: &'d mut [u8], | ||
| 174 | ) -> Self { | ||
| 175 | Self::new_inner(uarte, rxd.into(), txd.into(), None, None, config, rx_buffer, tx_buffer) | ||
| 176 | } | ||
| 177 | |||
| 178 | /// Create a new BufferedUarte with hardware flow control (RTS/CTS) | ||
| 179 | #[allow(clippy::too_many_arguments)] | ||
| 180 | pub fn new_with_rtscts( | ||
| 181 | uarte: Peri<'d, U>, | ||
| 182 | rxd: Peri<'d, impl GpioPin>, | ||
| 183 | txd: Peri<'d, impl GpioPin>, | ||
| 184 | cts: Peri<'d, impl GpioPin>, | ||
| 185 | rts: Peri<'d, impl GpioPin>, | ||
| 186 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 187 | config: Config, | ||
| 188 | rx_buffer: &'d mut [u8], | ||
| 189 | tx_buffer: &'d mut [u8], | ||
| 190 | ) -> Self { | ||
| 191 | Self::new_inner( | ||
| 192 | uarte, | ||
| 193 | rxd.into(), | ||
| 194 | txd.into(), | ||
| 195 | Some(cts.into()), | ||
| 196 | Some(rts.into()), | ||
| 197 | config, | ||
| 198 | rx_buffer, | ||
| 199 | tx_buffer, | ||
| 200 | ) | ||
| 201 | } | ||
| 202 | |||
| 203 | #[allow(clippy::too_many_arguments)] | ||
| 204 | fn new_inner( | ||
| 205 | peri: Peri<'d, U>, | ||
| 206 | rxd: Peri<'d, AnyPin>, | ||
| 207 | txd: Peri<'d, AnyPin>, | ||
| 208 | cts: Option<Peri<'d, AnyPin>>, | ||
| 209 | rts: Option<Peri<'d, AnyPin>>, | ||
| 210 | config: Config, | ||
| 211 | rx_buffer: &'d mut [u8], | ||
| 212 | tx_buffer: &'d mut [u8], | ||
| 213 | ) -> Self { | ||
| 214 | configure(U::regs(), config, cts.is_some()); | ||
| 215 | |||
| 216 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); | ||
| 217 | let rx = BufferedUarteRx::new_innerer(peri, rxd, rts, rx_buffer); | ||
| 218 | |||
| 219 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | ||
| 220 | U::Interrupt::pend(); | ||
| 221 | unsafe { U::Interrupt::enable() }; | ||
| 222 | |||
| 223 | U::state().tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 224 | |||
| 225 | Self { tx, rx } | ||
| 226 | } | ||
| 227 | |||
| 228 | /// Adjust the baud rate to the provided value. | ||
| 229 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | ||
| 230 | let r = U::regs(); | ||
| 231 | r.baudrate().write(|w| w.set_baudrate(baudrate)); | ||
| 232 | } | ||
| 233 | |||
| 234 | /// Split the UART in reader and writer parts. | ||
| 235 | /// | ||
| 236 | /// This allows reading and writing concurrently from independent tasks. | ||
| 237 | pub fn split(self) -> (BufferedUarteRx<'d, U>, BufferedUarteTx<'d, U>) { | ||
| 238 | (self.rx, self.tx) | ||
| 239 | } | ||
| 240 | |||
| 241 | /// Split the UART in reader and writer parts, by reference. | ||
| 242 | /// | ||
| 243 | /// The returned halves borrow from `self`, so you can drop them and go back to using | ||
| 244 | /// the "un-split" `self`. This allows temporarily splitting the UART. | ||
| 245 | pub fn split_by_ref(&mut self) -> (&mut BufferedUarteRx<'d, U>, &mut BufferedUarteTx<'d, U>) { | ||
| 246 | (&mut self.rx, &mut self.tx) | ||
| 247 | } | ||
| 248 | |||
| 249 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 250 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 251 | self.rx.read(buf).await | ||
| 252 | } | ||
| 253 | |||
| 254 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 255 | pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { | ||
| 256 | self.rx.fill_buf().await | ||
| 257 | } | ||
| 258 | |||
| 259 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | ||
| 260 | pub fn consume(&mut self, amt: usize) { | ||
| 261 | self.rx.consume(amt) | ||
| 262 | } | ||
| 263 | |||
| 264 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 265 | pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 266 | self.tx.write(buf).await | ||
| 267 | } | ||
| 268 | |||
| 269 | /// Try writing a buffer without waiting, returning how many bytes were written. | ||
| 270 | pub fn try_write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 271 | self.tx.try_write(buf) | ||
| 272 | } | ||
| 273 | |||
| 274 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | ||
| 275 | pub async fn flush(&mut self) -> Result<(), Error> { | ||
| 276 | self.tx.flush().await | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | /// Reader part of the buffered UARTE driver. | ||
| 281 | pub struct BufferedUarteTx<'d, U: UarteInstance> { | ||
| 282 | _peri: Peri<'d, U>, | ||
| 283 | } | ||
| 284 | |||
| 285 | impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | ||
| 286 | /// Create a new BufferedUarteTx without hardware flow control. | ||
| 287 | pub fn new( | ||
| 288 | uarte: Peri<'d, U>, | ||
| 289 | txd: Peri<'d, impl GpioPin>, | ||
| 290 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 291 | config: Config, | ||
| 292 | tx_buffer: &'d mut [u8], | ||
| 293 | ) -> Self { | ||
| 294 | Self::new_inner(uarte, txd.into(), None, config, tx_buffer) | ||
| 295 | } | ||
| 296 | |||
| 297 | /// Create a new BufferedUarte with hardware flow control (RTS/CTS) | ||
| 298 | pub fn new_with_cts( | ||
| 299 | uarte: Peri<'d, U>, | ||
| 300 | txd: Peri<'d, impl GpioPin>, | ||
| 301 | cts: Peri<'d, impl GpioPin>, | ||
| 302 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 303 | config: Config, | ||
| 304 | tx_buffer: &'d mut [u8], | ||
| 305 | ) -> Self { | ||
| 306 | Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer) | ||
| 307 | } | ||
| 308 | |||
| 309 | fn new_inner( | ||
| 310 | peri: Peri<'d, U>, | ||
| 311 | txd: Peri<'d, AnyPin>, | ||
| 312 | cts: Option<Peri<'d, AnyPin>>, | ||
| 313 | config: Config, | ||
| 314 | tx_buffer: &'d mut [u8], | ||
| 315 | ) -> Self { | ||
| 316 | configure(U::regs(), config, cts.is_some()); | ||
| 317 | |||
| 318 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); | ||
| 319 | |||
| 320 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | ||
| 321 | U::Interrupt::pend(); | ||
| 322 | unsafe { U::Interrupt::enable() }; | ||
| 323 | |||
| 324 | U::state().tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 325 | |||
| 326 | this | ||
| 327 | } | ||
| 328 | |||
| 329 | fn new_innerer( | ||
| 330 | peri: Peri<'d, U>, | ||
| 331 | txd: Peri<'d, AnyPin>, | ||
| 332 | cts: Option<Peri<'d, AnyPin>>, | ||
| 333 | tx_buffer: &'d mut [u8], | ||
| 334 | ) -> Self { | ||
| 335 | let r = U::regs(); | ||
| 336 | |||
| 337 | configure_tx_pins(r, txd, cts); | ||
| 338 | |||
| 339 | // Initialize state | ||
| 340 | let s = U::buffered_state(); | ||
| 341 | s.tx_count.store(0, Ordering::Relaxed); | ||
| 342 | let len = tx_buffer.len(); | ||
| 343 | unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||
| 344 | |||
| 345 | r.events_dma().tx().ready().write_value(0); | ||
| 346 | |||
| 347 | // Enable interrupts | ||
| 348 | r.intenset().write(|w| { | ||
| 349 | w.set_dmatxend(true); | ||
| 350 | }); | ||
| 351 | |||
| 352 | Self { _peri: peri } | ||
| 353 | } | ||
| 354 | |||
| 355 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 356 | pub fn write<'a>(&'a mut self, buf: &'a [u8]) -> impl Future<Output = Result<usize, Error>> + 'a { | ||
| 357 | poll_fn(move |cx| { | ||
| 358 | //trace!("poll_write: {:?}", buf.len()); | ||
| 359 | let ss = U::state(); | ||
| 360 | let s = U::buffered_state(); | ||
| 361 | let mut tx = unsafe { s.tx_buf.writer() }; | ||
| 362 | |||
| 363 | let tx_buf = tx.push_slice(); | ||
| 364 | if tx_buf.is_empty() { | ||
| 365 | //trace!("poll_write: pending"); | ||
| 366 | ss.tx_waker.register(cx.waker()); | ||
| 367 | return Poll::Pending; | ||
| 368 | } | ||
| 369 | |||
| 370 | let n = min(tx_buf.len(), buf.len()); | ||
| 371 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 372 | tx.push_done(n); | ||
| 373 | |||
| 374 | //trace!("poll_write: queued {:?}", n); | ||
| 375 | |||
| 376 | compiler_fence(Ordering::SeqCst); | ||
| 377 | U::Interrupt::pend(); | ||
| 378 | |||
| 379 | Poll::Ready(Ok(n)) | ||
| 380 | }) | ||
| 381 | } | ||
| 382 | |||
| 383 | /// Try writing a buffer without waiting, returning how many bytes were written. | ||
| 384 | pub fn try_write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 385 | //trace!("poll_write: {:?}", buf.len()); | ||
| 386 | let s = U::buffered_state(); | ||
| 387 | let mut tx = unsafe { s.tx_buf.writer() }; | ||
| 388 | |||
| 389 | let tx_buf = tx.push_slice(); | ||
| 390 | if tx_buf.is_empty() { | ||
| 391 | return Ok(0); | ||
| 392 | } | ||
| 393 | |||
| 394 | let n = min(tx_buf.len(), buf.len()); | ||
| 395 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 396 | tx.push_done(n); | ||
| 397 | |||
| 398 | //trace!("poll_write: queued {:?}", n); | ||
| 399 | |||
| 400 | compiler_fence(Ordering::SeqCst); | ||
| 401 | U::Interrupt::pend(); | ||
| 402 | |||
| 403 | Ok(n) | ||
| 404 | } | ||
| 405 | |||
| 406 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | ||
| 407 | pub fn flush(&mut self) -> impl Future<Output = Result<(), Error>> + '_ { | ||
| 408 | poll_fn(move |cx| { | ||
| 409 | //trace!("poll_flush"); | ||
| 410 | let ss = U::state(); | ||
| 411 | let s = U::buffered_state(); | ||
| 412 | if !s.tx_buf.is_empty() { | ||
| 413 | //trace!("poll_flush: pending"); | ||
| 414 | ss.tx_waker.register(cx.waker()); | ||
| 415 | return Poll::Pending; | ||
| 416 | } | ||
| 417 | |||
| 418 | Poll::Ready(Ok(())) | ||
| 419 | }) | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { | ||
| 424 | fn drop(&mut self) { | ||
| 425 | let r = U::regs(); | ||
| 426 | |||
| 427 | r.intenclr().write(|w| { | ||
| 428 | w.set_txdrdy(true); | ||
| 429 | w.set_dmatxready(true); | ||
| 430 | w.set_txstopped(true); | ||
| 431 | }); | ||
| 432 | r.events_txstopped().write_value(0); | ||
| 433 | r.tasks_dma().tx().stop().write_value(1); | ||
| 434 | while r.events_txstopped().read() == 0 {} | ||
| 435 | |||
| 436 | let s = U::buffered_state(); | ||
| 437 | unsafe { s.tx_buf.deinit() } | ||
| 438 | |||
| 439 | let s = U::state(); | ||
| 440 | drop_tx_rx(r, s); | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | /// Reader part of the buffered UARTE driver. | ||
| 445 | pub struct BufferedUarteRx<'d, U: UarteInstance> { | ||
| 446 | _peri: Peri<'d, U>, | ||
| 447 | } | ||
| 448 | |||
| 449 | impl<'d, U: UarteInstance> BufferedUarteRx<'d, U> { | ||
| 450 | /// Create a new BufferedUarte without hardware flow control. | ||
| 451 | #[allow(clippy::too_many_arguments)] | ||
| 452 | pub fn new( | ||
| 453 | uarte: Peri<'d, U>, | ||
| 454 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 455 | rxd: Peri<'d, impl GpioPin>, | ||
| 456 | config: Config, | ||
| 457 | rx_buffer: &'d mut [u8], | ||
| 458 | ) -> Self { | ||
| 459 | Self::new_inner(uarte, rxd.into(), None, config, rx_buffer) | ||
| 460 | } | ||
| 461 | |||
| 462 | /// Create a new BufferedUarte with hardware flow control (RTS/CTS) | ||
| 463 | #[allow(clippy::too_many_arguments)] | ||
| 464 | pub fn new_with_rts( | ||
| 465 | uarte: Peri<'d, U>, | ||
| 466 | rxd: Peri<'d, impl GpioPin>, | ||
| 467 | rts: Peri<'d, impl GpioPin>, | ||
| 468 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | ||
| 469 | config: Config, | ||
| 470 | rx_buffer: &'d mut [u8], | ||
| 471 | ) -> Self { | ||
| 472 | Self::new_inner(uarte, rxd.into(), Some(rts.into()), config, rx_buffer) | ||
| 473 | } | ||
| 474 | |||
| 475 | #[allow(clippy::too_many_arguments)] | ||
| 476 | fn new_inner( | ||
| 477 | peri: Peri<'d, U>, | ||
| 478 | rxd: Peri<'d, AnyPin>, | ||
| 479 | rts: Option<Peri<'d, AnyPin>>, | ||
| 480 | config: Config, | ||
| 481 | rx_buffer: &'d mut [u8], | ||
| 482 | ) -> Self { | ||
| 483 | configure(U::regs(), config, rts.is_some()); | ||
| 484 | |||
| 485 | let this = Self::new_innerer(peri, rxd, rts, rx_buffer); | ||
| 486 | |||
| 487 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | ||
| 488 | U::Interrupt::pend(); | ||
| 489 | unsafe { U::Interrupt::enable() }; | ||
| 490 | |||
| 491 | U::state().tx_rx_refcount.store(1, Ordering::Relaxed); | ||
| 492 | |||
| 493 | this | ||
| 494 | } | ||
| 495 | |||
| 496 | #[allow(clippy::too_many_arguments)] | ||
| 497 | fn new_innerer( | ||
| 498 | peri: Peri<'d, U>, | ||
| 499 | rxd: Peri<'d, AnyPin>, | ||
| 500 | rts: Option<Peri<'d, AnyPin>>, | ||
| 501 | rx_buffer: &'d mut [u8], | ||
| 502 | ) -> Self { | ||
| 503 | let r = U::regs(); | ||
| 504 | |||
| 505 | configure_rx_pins(r, rxd, rts); | ||
| 506 | |||
| 507 | // Initialize state | ||
| 508 | let s = U::buffered_state(); | ||
| 509 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); | ||
| 510 | let rx_ptr = rx_buffer.as_mut_ptr(); | ||
| 511 | unsafe { s.rx_buf.init(rx_ptr, rx_len) }; | ||
| 512 | |||
| 513 | // clear errors | ||
| 514 | let errors = r.errorsrc().read(); | ||
| 515 | r.errorsrc().write_value(errors); | ||
| 516 | |||
| 517 | r.events_error().write_value(0); | ||
| 518 | r.events_dma().rx().end().write_value(0); | ||
| 519 | |||
| 520 | // set timeout-to-stop short | ||
| 521 | r.shorts().write(|w| { | ||
| 522 | w.set_frametimeout_dma_rx_stop(true); | ||
| 523 | }); | ||
| 524 | |||
| 525 | // set default timeout | ||
| 526 | r.frametimeout().write_value(pac::uarte::regs::Frametimeout(0x10)); | ||
| 527 | |||
| 528 | // Enable interrupts | ||
| 529 | r.intenset().write(|w| { | ||
| 530 | w.set_dmatxend(true); | ||
| 531 | w.set_error(true); | ||
| 532 | w.set_dmarxend(true); | ||
| 533 | }); | ||
| 534 | |||
| 535 | Self { _peri: peri } | ||
| 536 | } | ||
| 537 | |||
| 538 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 539 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 540 | let data = self.fill_buf().await?; | ||
| 541 | let n = data.len().min(buf.len()); | ||
| 542 | buf[..n].copy_from_slice(&data[..n]); | ||
| 543 | self.consume(n); | ||
| 544 | Ok(n) | ||
| 545 | } | ||
| 546 | |||
| 547 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 548 | pub fn fill_buf(&mut self) -> impl Future<Output = Result<&'_ [u8], Error>> { | ||
| 549 | poll_fn(move |cx| { | ||
| 550 | compiler_fence(Ordering::SeqCst); | ||
| 551 | //trace!("poll_read"); | ||
| 552 | |||
| 553 | let s = U::buffered_state(); | ||
| 554 | let ss = U::state(); | ||
| 555 | let mut rx = unsafe { s.rx_buf.reader() }; | ||
| 556 | |||
| 557 | let (ptr, n) = rx.pop_buf(); | ||
| 558 | if n == 0 { | ||
| 559 | //trace!(" empty"); | ||
| 560 | ss.rx_waker.register(cx.waker()); | ||
| 561 | Poll::Pending | ||
| 562 | } else { | ||
| 563 | Poll::Ready(Ok(unsafe { slice::from_raw_parts(ptr, n) })) | ||
| 564 | } | ||
| 565 | }) | ||
| 566 | } | ||
| 567 | |||
| 568 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | ||
| 569 | pub fn consume(&mut self, amt: usize) { | ||
| 570 | if amt == 0 { | ||
| 571 | return; | ||
| 572 | } | ||
| 573 | |||
| 574 | let s = U::buffered_state(); | ||
| 575 | let mut rx = unsafe { s.rx_buf.reader() }; | ||
| 576 | rx.pop_done(amt); | ||
| 577 | } | ||
| 578 | |||
| 579 | /// we are ready to read if there is data in the buffer | ||
| 580 | fn read_ready() -> Result<bool, Error> { | ||
| 581 | let state = U::buffered_state(); | ||
| 582 | Ok(!state.rx_buf.is_empty()) | ||
| 583 | } | ||
| 584 | } | ||
| 585 | |||
| 586 | impl<'a, U: UarteInstance> Drop for BufferedUarteRx<'a, U> { | ||
| 587 | fn drop(&mut self) { | ||
| 588 | let r = U::regs(); | ||
| 589 | |||
| 590 | r.intenclr().write(|w| { | ||
| 591 | w.set_rxto(true); | ||
| 592 | }); | ||
| 593 | r.events_rxto().write_value(0); | ||
| 594 | |||
| 595 | let s = U::buffered_state(); | ||
| 596 | unsafe { s.rx_buf.deinit() } | ||
| 597 | |||
| 598 | let s = U::state(); | ||
| 599 | drop_tx_rx(r, s); | ||
| 600 | } | ||
| 601 | } | ||
| 602 | |||
| 603 | mod _embedded_io { | ||
| 604 | use super::*; | ||
| 605 | |||
| 606 | impl embedded_io_async::Error for Error { | ||
| 607 | fn kind(&self) -> embedded_io_async::ErrorKind { | ||
| 608 | match *self {} | ||
| 609 | } | ||
| 610 | } | ||
| 611 | |||
| 612 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarte<'d, U> { | ||
| 613 | type Error = Error; | ||
| 614 | } | ||
| 615 | |||
| 616 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteRx<'d, U> { | ||
| 617 | type Error = Error; | ||
| 618 | } | ||
| 619 | |||
| 620 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteTx<'d, U> { | ||
| 621 | type Error = Error; | ||
| 622 | } | ||
| 623 | |||
| 624 | impl<'d, U: UarteInstance> embedded_io_async::Read for BufferedUarte<'d, U> { | ||
| 625 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | ||
| 626 | self.read(buf).await | ||
| 627 | } | ||
| 628 | } | ||
| 629 | |||
| 630 | impl<'d: 'd, U: UarteInstance> embedded_io_async::Read for BufferedUarteRx<'d, U> { | ||
| 631 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | ||
| 632 | self.read(buf).await | ||
| 633 | } | ||
| 634 | } | ||
| 635 | |||
| 636 | impl<'d, U: UarteInstance> embedded_io_async::ReadReady for BufferedUarte<'d, U> { | ||
| 637 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | ||
| 638 | BufferedUarteRx::<'d, U>::read_ready() | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 642 | impl<'d, U: UarteInstance> embedded_io_async::ReadReady for BufferedUarteRx<'d, U> { | ||
| 643 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | ||
| 644 | Self::read_ready() | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | impl<'d, U: UarteInstance> embedded_io_async::BufRead for BufferedUarte<'d, U> { | ||
| 649 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | ||
| 650 | self.fill_buf().await | ||
| 651 | } | ||
| 652 | |||
| 653 | fn consume(&mut self, amt: usize) { | ||
| 654 | self.consume(amt) | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | impl<'d: 'd, U: UarteInstance> embedded_io_async::BufRead for BufferedUarteRx<'d, U> { | ||
| 659 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | ||
| 660 | self.fill_buf().await | ||
| 661 | } | ||
| 662 | |||
| 663 | fn consume(&mut self, amt: usize) { | ||
| 664 | self.consume(amt) | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | impl<'d, U: UarteInstance> embedded_io_async::Write for BufferedUarte<'d, U> { | ||
| 669 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | ||
| 670 | self.write(buf).await | ||
| 671 | } | ||
| 672 | |||
| 673 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 674 | self.flush().await | ||
| 675 | } | ||
| 676 | } | ||
| 677 | |||
| 678 | impl<'d: 'd, U: UarteInstance> embedded_io_async::Write for BufferedUarteTx<'d, U> { | ||
| 679 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | ||
| 680 | self.write(buf).await | ||
| 681 | } | ||
| 682 | |||
| 683 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 684 | self.flush().await | ||
| 685 | } | ||
| 686 | } | ||
| 687 | } | ||
diff --git a/embassy-nrf/src/chips/nrf51.rs b/embassy-nrf/src/chips/nrf51.rs index 3976e8ff0..1184c4409 100644 --- a/embassy-nrf/src/chips/nrf51.rs +++ b/embassy-nrf/src/chips/nrf51.rs | |||
| @@ -115,6 +115,11 @@ impl_rtc!(RTC0, RTC0, RTC0); | |||
| 115 | #[cfg(not(feature = "time-driver-rtc1"))] | 115 | #[cfg(not(feature = "time-driver-rtc1"))] |
| 116 | impl_rtc!(RTC1, RTC1, RTC1); | 116 | impl_rtc!(RTC1, RTC1, RTC1); |
| 117 | 117 | ||
| 118 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 119 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 120 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 121 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 122 | |||
| 118 | impl_pin!(P0_00, 0, 0); | 123 | impl_pin!(P0_00, 0, 0); |
| 119 | impl_pin!(P0_01, 0, 1); | 124 | impl_pin!(P0_01, 0, 1); |
| 120 | impl_pin!(P0_02, 0, 2); | 125 | impl_pin!(P0_02, 0, 2); |
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs index 63ba6999a..dd2e66927 100644 --- a/embassy-nrf/src/chips/nrf52805.rs +++ b/embassy-nrf/src/chips/nrf52805.rs | |||
| @@ -195,28 +195,35 @@ impl_pin!(P0_29, 0, 29); | |||
| 195 | impl_pin!(P0_30, 0, 30); | 195 | impl_pin!(P0_30, 0, 30); |
| 196 | impl_pin!(P0_31, 0, 31); | 196 | impl_pin!(P0_31, 0, 31); |
| 197 | 197 | ||
| 198 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 198 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 199 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 199 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 200 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 200 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 201 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 201 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 202 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 202 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 203 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 203 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 204 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 204 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 205 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 205 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 206 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 206 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 207 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 207 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 208 | impl_ppi_channel!(PPI_CH20, 20 => static); | 208 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 209 | impl_ppi_channel!(PPI_CH21, 21 => static); | 209 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 210 | impl_ppi_channel!(PPI_CH22, 22 => static); | 210 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 211 | impl_ppi_channel!(PPI_CH23, 23 => static); | 211 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 212 | impl_ppi_channel!(PPI_CH24, 24 => static); | 212 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 213 | impl_ppi_channel!(PPI_CH25, 25 => static); | 213 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 214 | impl_ppi_channel!(PPI_CH26, 26 => static); | 214 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 215 | impl_ppi_channel!(PPI_CH27, 27 => static); | 215 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 216 | impl_ppi_channel!(PPI_CH28, 28 => static); | 216 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 217 | impl_ppi_channel!(PPI_CH29, 29 => static); | 217 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 218 | impl_ppi_channel!(PPI_CH30, 30 => static); | 218 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 219 | impl_ppi_channel!(PPI_CH31, 31 => static); | 219 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 220 | |||
| 221 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 222 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 223 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 224 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 225 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 226 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 220 | 227 | ||
| 221 | impl_saadc_input!(P0_04, ANALOG_INPUT2); | 228 | impl_saadc_input!(P0_04, ANALOG_INPUT2); |
| 222 | impl_saadc_input!(P0_05, ANALOG_INPUT3); | 229 | impl_saadc_input!(P0_05, ANALOG_INPUT3); |
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs index 7f744f9fb..7acb53a03 100644 --- a/embassy-nrf/src/chips/nrf52810.rs +++ b/embassy-nrf/src/chips/nrf52810.rs | |||
| @@ -205,38 +205,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 205 | impl_pin!(P0_30, 0, 30); | 205 | impl_pin!(P0_30, 0, 30); |
| 206 | impl_pin!(P0_31, 0, 31); | 206 | impl_pin!(P0_31, 0, 31); |
| 207 | 207 | ||
| 208 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 208 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 209 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 209 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 210 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 210 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 211 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 211 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 212 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 212 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 213 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 213 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 214 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 214 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 215 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 215 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 216 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 216 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 217 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 217 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 218 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 218 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 219 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 219 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 220 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 220 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 221 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 221 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 222 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 222 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 223 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 223 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 224 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 224 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 225 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 225 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 226 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 226 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 227 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 227 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 228 | impl_ppi_channel!(PPI_CH20, 20 => static); | 228 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 229 | impl_ppi_channel!(PPI_CH21, 21 => static); | 229 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 230 | impl_ppi_channel!(PPI_CH22, 22 => static); | 230 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 231 | impl_ppi_channel!(PPI_CH23, 23 => static); | 231 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 232 | impl_ppi_channel!(PPI_CH24, 24 => static); | 232 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 233 | impl_ppi_channel!(PPI_CH25, 25 => static); | 233 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 234 | impl_ppi_channel!(PPI_CH26, 26 => static); | 234 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 235 | impl_ppi_channel!(PPI_CH27, 27 => static); | 235 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 236 | impl_ppi_channel!(PPI_CH28, 28 => static); | 236 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 237 | impl_ppi_channel!(PPI_CH29, 29 => static); | 237 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 238 | impl_ppi_channel!(PPI_CH30, 30 => static); | 238 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 239 | impl_ppi_channel!(PPI_CH31, 31 => static); | 239 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 240 | |||
| 241 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 242 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 243 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 244 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 245 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 246 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 240 | 247 | ||
| 241 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 248 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 242 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 249 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs index 908167e31..4178ef6cd 100644 --- a/embassy-nrf/src/chips/nrf52811.rs +++ b/embassy-nrf/src/chips/nrf52811.rs | |||
| @@ -207,38 +207,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 207 | impl_pin!(P0_30, 0, 30); | 207 | impl_pin!(P0_30, 0, 30); |
| 208 | impl_pin!(P0_31, 0, 31); | 208 | impl_pin!(P0_31, 0, 31); |
| 209 | 209 | ||
| 210 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 210 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 211 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 211 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 212 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 212 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 213 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 213 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 214 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 214 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 215 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 215 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 216 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 216 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 217 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 217 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 218 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 218 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 219 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 219 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 220 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 220 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 221 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 221 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 222 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 222 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 223 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 223 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 224 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 224 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 225 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 225 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 226 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 226 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 227 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 227 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 228 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 228 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 229 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 229 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 230 | impl_ppi_channel!(PPI_CH20, 20 => static); | 230 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 231 | impl_ppi_channel!(PPI_CH21, 21 => static); | 231 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 232 | impl_ppi_channel!(PPI_CH22, 22 => static); | 232 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 233 | impl_ppi_channel!(PPI_CH23, 23 => static); | 233 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 234 | impl_ppi_channel!(PPI_CH24, 24 => static); | 234 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 235 | impl_ppi_channel!(PPI_CH25, 25 => static); | 235 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 236 | impl_ppi_channel!(PPI_CH26, 26 => static); | 236 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 237 | impl_ppi_channel!(PPI_CH27, 27 => static); | 237 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 238 | impl_ppi_channel!(PPI_CH28, 28 => static); | 238 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 239 | impl_ppi_channel!(PPI_CH29, 29 => static); | 239 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 240 | impl_ppi_channel!(PPI_CH30, 30 => static); | 240 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 241 | impl_ppi_channel!(PPI_CH31, 31 => static); | 241 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 242 | |||
| 243 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 244 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 245 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 246 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 247 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 248 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 242 | 249 | ||
| 243 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 250 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 244 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 251 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs index 22360575b..32304b3ea 100644 --- a/embassy-nrf/src/chips/nrf52820.rs +++ b/embassy-nrf/src/chips/nrf52820.rs | |||
| @@ -207,38 +207,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 207 | impl_pin!(P0_30, 0, 30); | 207 | impl_pin!(P0_30, 0, 30); |
| 208 | impl_pin!(P0_31, 0, 31); | 208 | impl_pin!(P0_31, 0, 31); |
| 209 | 209 | ||
| 210 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 210 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 211 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 211 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 212 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 212 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 213 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 213 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 214 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 214 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 215 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 215 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 216 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 216 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 217 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 217 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 218 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 218 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 219 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 219 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 220 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 220 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 221 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 221 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 222 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 222 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 223 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 223 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 224 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 224 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 225 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 225 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 226 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 226 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 227 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 227 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 228 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 228 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 229 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 229 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 230 | impl_ppi_channel!(PPI_CH20, 20 => static); | 230 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 231 | impl_ppi_channel!(PPI_CH21, 21 => static); | 231 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 232 | impl_ppi_channel!(PPI_CH22, 22 => static); | 232 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 233 | impl_ppi_channel!(PPI_CH23, 23 => static); | 233 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 234 | impl_ppi_channel!(PPI_CH24, 24 => static); | 234 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 235 | impl_ppi_channel!(PPI_CH25, 25 => static); | 235 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 236 | impl_ppi_channel!(PPI_CH26, 26 => static); | 236 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 237 | impl_ppi_channel!(PPI_CH27, 27 => static); | 237 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 238 | impl_ppi_channel!(PPI_CH28, 28 => static); | 238 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 239 | impl_ppi_channel!(PPI_CH29, 29 => static); | 239 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 240 | impl_ppi_channel!(PPI_CH30, 30 => static); | 240 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 241 | impl_ppi_channel!(PPI_CH31, 31 => static); | 241 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 242 | |||
| 243 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 244 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 245 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 246 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 247 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 248 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 242 | 249 | ||
| 243 | impl_radio!(RADIO, RADIO, RADIO); | 250 | impl_radio!(RADIO, RADIO, RADIO); |
| 244 | 251 | ||
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs index 1598df3fe..06363a467 100644 --- a/embassy-nrf/src/chips/nrf52832.rs +++ b/embassy-nrf/src/chips/nrf52832.rs | |||
| @@ -240,38 +240,45 @@ impl_pin!(P0_29, 0, 29); | |||
| 240 | impl_pin!(P0_30, 0, 30); | 240 | impl_pin!(P0_30, 0, 30); |
| 241 | impl_pin!(P0_31, 0, 31); | 241 | impl_pin!(P0_31, 0, 31); |
| 242 | 242 | ||
| 243 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 243 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 244 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 244 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 245 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 245 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 246 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 246 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 247 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 247 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 248 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 248 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 249 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 249 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 250 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 250 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 251 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 251 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 252 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 252 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 253 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 253 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 254 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 254 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 255 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 255 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 256 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 256 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 257 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 257 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 258 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 258 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 259 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 259 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 260 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 260 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 261 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 261 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 262 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 262 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 263 | impl_ppi_channel!(PPI_CH20, 20 => static); | 263 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 264 | impl_ppi_channel!(PPI_CH21, 21 => static); | 264 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 265 | impl_ppi_channel!(PPI_CH22, 22 => static); | 265 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 266 | impl_ppi_channel!(PPI_CH23, 23 => static); | 266 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 267 | impl_ppi_channel!(PPI_CH24, 24 => static); | 267 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 268 | impl_ppi_channel!(PPI_CH25, 25 => static); | 268 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 269 | impl_ppi_channel!(PPI_CH26, 26 => static); | 269 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 270 | impl_ppi_channel!(PPI_CH27, 27 => static); | 270 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 271 | impl_ppi_channel!(PPI_CH28, 28 => static); | 271 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 272 | impl_ppi_channel!(PPI_CH29, 29 => static); | 272 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 273 | impl_ppi_channel!(PPI_CH30, 30 => static); | 273 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 274 | impl_ppi_channel!(PPI_CH31, 31 => static); | 274 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 275 | |||
| 276 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 277 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 278 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 279 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 280 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 281 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 275 | 282 | ||
| 276 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 283 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 277 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 284 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs index 6931fb064..754943d33 100644 --- a/embassy-nrf/src/chips/nrf52833.rs +++ b/embassy-nrf/src/chips/nrf52833.rs | |||
| @@ -282,38 +282,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 282 | impl_pin!(P1_14, 1, 14); | 282 | impl_pin!(P1_14, 1, 14); |
| 283 | impl_pin!(P1_15, 1, 15); | 283 | impl_pin!(P1_15, 1, 15); |
| 284 | 284 | ||
| 285 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 285 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 286 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 286 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 287 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 287 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 288 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 288 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 289 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 289 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 290 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 290 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 291 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 291 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 292 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 292 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 293 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 293 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 294 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 294 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 295 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 295 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 296 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 296 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 297 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 297 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 298 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 298 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 299 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 299 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 300 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 300 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 301 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 301 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 302 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 302 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 303 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 303 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 304 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 304 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 305 | impl_ppi_channel!(PPI_CH20, 20 => static); | 305 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 306 | impl_ppi_channel!(PPI_CH21, 21 => static); | 306 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 307 | impl_ppi_channel!(PPI_CH22, 22 => static); | 307 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 308 | impl_ppi_channel!(PPI_CH23, 23 => static); | 308 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 309 | impl_ppi_channel!(PPI_CH24, 24 => static); | 309 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 310 | impl_ppi_channel!(PPI_CH25, 25 => static); | 310 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 311 | impl_ppi_channel!(PPI_CH26, 26 => static); | 311 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 312 | impl_ppi_channel!(PPI_CH27, 27 => static); | 312 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 313 | impl_ppi_channel!(PPI_CH28, 28 => static); | 313 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 314 | impl_ppi_channel!(PPI_CH29, 29 => static); | 314 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 315 | impl_ppi_channel!(PPI_CH30, 30 => static); | 315 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 316 | impl_ppi_channel!(PPI_CH31, 31 => static); | 316 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 317 | |||
| 318 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 319 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 320 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 321 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 322 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 323 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 317 | 324 | ||
| 318 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 325 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 319 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 326 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs index 5fa521aae..ac07cd820 100644 --- a/embassy-nrf/src/chips/nrf52840.rs +++ b/embassy-nrf/src/chips/nrf52840.rs | |||
| @@ -287,38 +287,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 287 | impl_pin!(P1_14, 1, 14); | 287 | impl_pin!(P1_14, 1, 14); |
| 288 | impl_pin!(P1_15, 1, 15); | 288 | impl_pin!(P1_15, 1, 15); |
| 289 | 289 | ||
| 290 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 290 | impl_ppi_channel!(PPI_CH0, PPI, 0 => configurable); |
| 291 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 291 | impl_ppi_channel!(PPI_CH1, PPI, 1 => configurable); |
| 292 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 292 | impl_ppi_channel!(PPI_CH2, PPI, 2 => configurable); |
| 293 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 293 | impl_ppi_channel!(PPI_CH3, PPI, 3 => configurable); |
| 294 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 294 | impl_ppi_channel!(PPI_CH4, PPI, 4 => configurable); |
| 295 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 295 | impl_ppi_channel!(PPI_CH5, PPI, 5 => configurable); |
| 296 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 296 | impl_ppi_channel!(PPI_CH6, PPI, 6 => configurable); |
| 297 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 297 | impl_ppi_channel!(PPI_CH7, PPI, 7 => configurable); |
| 298 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 298 | impl_ppi_channel!(PPI_CH8, PPI, 8 => configurable); |
| 299 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 299 | impl_ppi_channel!(PPI_CH9, PPI, 9 => configurable); |
| 300 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 300 | impl_ppi_channel!(PPI_CH10, PPI, 10 => configurable); |
| 301 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 301 | impl_ppi_channel!(PPI_CH11, PPI, 11 => configurable); |
| 302 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 302 | impl_ppi_channel!(PPI_CH12, PPI, 12 => configurable); |
| 303 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 303 | impl_ppi_channel!(PPI_CH13, PPI, 13 => configurable); |
| 304 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 304 | impl_ppi_channel!(PPI_CH14, PPI, 14 => configurable); |
| 305 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 305 | impl_ppi_channel!(PPI_CH15, PPI, 15 => configurable); |
| 306 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 306 | impl_ppi_channel!(PPI_CH16, PPI, 16 => configurable); |
| 307 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 307 | impl_ppi_channel!(PPI_CH17, PPI, 17 => configurable); |
| 308 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 308 | impl_ppi_channel!(PPI_CH18, PPI, 18 => configurable); |
| 309 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 309 | impl_ppi_channel!(PPI_CH19, PPI, 19 => configurable); |
| 310 | impl_ppi_channel!(PPI_CH20, 20 => static); | 310 | impl_ppi_channel!(PPI_CH20, PPI, 20 => static); |
| 311 | impl_ppi_channel!(PPI_CH21, 21 => static); | 311 | impl_ppi_channel!(PPI_CH21, PPI, 21 => static); |
| 312 | impl_ppi_channel!(PPI_CH22, 22 => static); | 312 | impl_ppi_channel!(PPI_CH22, PPI, 22 => static); |
| 313 | impl_ppi_channel!(PPI_CH23, 23 => static); | 313 | impl_ppi_channel!(PPI_CH23, PPI, 23 => static); |
| 314 | impl_ppi_channel!(PPI_CH24, 24 => static); | 314 | impl_ppi_channel!(PPI_CH24, PPI, 24 => static); |
| 315 | impl_ppi_channel!(PPI_CH25, 25 => static); | 315 | impl_ppi_channel!(PPI_CH25, PPI, 25 => static); |
| 316 | impl_ppi_channel!(PPI_CH26, 26 => static); | 316 | impl_ppi_channel!(PPI_CH26, PPI, 26 => static); |
| 317 | impl_ppi_channel!(PPI_CH27, 27 => static); | 317 | impl_ppi_channel!(PPI_CH27, PPI, 27 => static); |
| 318 | impl_ppi_channel!(PPI_CH28, 28 => static); | 318 | impl_ppi_channel!(PPI_CH28, PPI, 28 => static); |
| 319 | impl_ppi_channel!(PPI_CH29, 29 => static); | 319 | impl_ppi_channel!(PPI_CH29, PPI, 29 => static); |
| 320 | impl_ppi_channel!(PPI_CH30, 30 => static); | 320 | impl_ppi_channel!(PPI_CH30, PPI, 30 => static); |
| 321 | impl_ppi_channel!(PPI_CH31, 31 => static); | 321 | impl_ppi_channel!(PPI_CH31, PPI, 31 => static); |
| 322 | |||
| 323 | impl_ppi_group!(PPI_GROUP0, PPI, 0); | ||
| 324 | impl_ppi_group!(PPI_GROUP1, PPI, 1); | ||
| 325 | impl_ppi_group!(PPI_GROUP2, PPI, 2); | ||
| 326 | impl_ppi_group!(PPI_GROUP3, PPI, 3); | ||
| 327 | impl_ppi_group!(PPI_GROUP4, PPI, 4); | ||
| 328 | impl_ppi_group!(PPI_GROUP5, PPI, 5); | ||
| 322 | 329 | ||
| 323 | impl_saadc_input!(P0_02, ANALOG_INPUT0); | 330 | impl_saadc_input!(P0_02, ANALOG_INPUT0); |
| 324 | impl_saadc_input!(P0_03, ANALOG_INPUT1); | 331 | impl_saadc_input!(P0_03, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs index 730c9842d..aa51527fb 100644 --- a/embassy-nrf/src/chips/nrf5340_app.rs +++ b/embassy-nrf/src/chips/nrf5340_app.rs | |||
| @@ -435,38 +435,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 435 | impl_pin!(P1_14, 1, 14); | 435 | impl_pin!(P1_14, 1, 14); |
| 436 | impl_pin!(P1_15, 1, 15); | 436 | impl_pin!(P1_15, 1, 15); |
| 437 | 437 | ||
| 438 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 438 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 439 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 439 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 440 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 440 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 441 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 441 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 442 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 442 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 443 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 443 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 444 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 444 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 445 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 445 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 446 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 446 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 447 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 447 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 448 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 448 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 449 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 449 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 450 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 450 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 451 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 451 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 452 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 452 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 453 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 453 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 454 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 454 | impl_ppi_channel!(PPI_CH16, DPPIC, 16 => configurable); |
| 455 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 455 | impl_ppi_channel!(PPI_CH17, DPPIC, 17 => configurable); |
| 456 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 456 | impl_ppi_channel!(PPI_CH18, DPPIC, 18 => configurable); |
| 457 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 457 | impl_ppi_channel!(PPI_CH19, DPPIC, 19 => configurable); |
| 458 | impl_ppi_channel!(PPI_CH20, 20 => configurable); | 458 | impl_ppi_channel!(PPI_CH20, DPPIC, 20 => configurable); |
| 459 | impl_ppi_channel!(PPI_CH21, 21 => configurable); | 459 | impl_ppi_channel!(PPI_CH21, DPPIC, 21 => configurable); |
| 460 | impl_ppi_channel!(PPI_CH22, 22 => configurable); | 460 | impl_ppi_channel!(PPI_CH22, DPPIC, 22 => configurable); |
| 461 | impl_ppi_channel!(PPI_CH23, 23 => configurable); | 461 | impl_ppi_channel!(PPI_CH23, DPPIC, 23 => configurable); |
| 462 | impl_ppi_channel!(PPI_CH24, 24 => configurable); | 462 | impl_ppi_channel!(PPI_CH24, DPPIC, 24 => configurable); |
| 463 | impl_ppi_channel!(PPI_CH25, 25 => configurable); | 463 | impl_ppi_channel!(PPI_CH25, DPPIC, 25 => configurable); |
| 464 | impl_ppi_channel!(PPI_CH26, 26 => configurable); | 464 | impl_ppi_channel!(PPI_CH26, DPPIC, 26 => configurable); |
| 465 | impl_ppi_channel!(PPI_CH27, 27 => configurable); | 465 | impl_ppi_channel!(PPI_CH27, DPPIC, 27 => configurable); |
| 466 | impl_ppi_channel!(PPI_CH28, 28 => configurable); | 466 | impl_ppi_channel!(PPI_CH28, DPPIC, 28 => configurable); |
| 467 | impl_ppi_channel!(PPI_CH29, 29 => configurable); | 467 | impl_ppi_channel!(PPI_CH29, DPPIC, 29 => configurable); |
| 468 | impl_ppi_channel!(PPI_CH30, 30 => configurable); | 468 | impl_ppi_channel!(PPI_CH30, DPPIC, 30 => configurable); |
| 469 | impl_ppi_channel!(PPI_CH31, 31 => configurable); | 469 | impl_ppi_channel!(PPI_CH31, DPPIC, 31 => configurable); |
| 470 | |||
| 471 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 472 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 473 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 474 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 475 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 476 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 470 | 477 | ||
| 471 | impl_saadc_input!(P0_04, ANALOG_INPUT0); | 478 | impl_saadc_input!(P0_04, ANALOG_INPUT0); |
| 472 | impl_saadc_input!(P0_05, ANALOG_INPUT1); | 479 | impl_saadc_input!(P0_05, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs index 413afc5c5..2207e7bda 100644 --- a/embassy-nrf/src/chips/nrf5340_net.rs +++ b/embassy-nrf/src/chips/nrf5340_net.rs | |||
| @@ -275,38 +275,45 @@ impl_pin!(P1_13, 1, 13); | |||
| 275 | impl_pin!(P1_14, 1, 14); | 275 | impl_pin!(P1_14, 1, 14); |
| 276 | impl_pin!(P1_15, 1, 15); | 276 | impl_pin!(P1_15, 1, 15); |
| 277 | 277 | ||
| 278 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 278 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 279 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 279 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 280 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 280 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 281 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 281 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 282 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 282 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 283 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 283 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 284 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 284 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 285 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 285 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 286 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 286 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 287 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 287 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 288 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 288 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 289 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 289 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 290 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 290 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 291 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 291 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 292 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 292 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 293 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 293 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 294 | impl_ppi_channel!(PPI_CH16, 16 => configurable); | 294 | impl_ppi_channel!(PPI_CH16, DPPIC, 16 => configurable); |
| 295 | impl_ppi_channel!(PPI_CH17, 17 => configurable); | 295 | impl_ppi_channel!(PPI_CH17, DPPIC, 17 => configurable); |
| 296 | impl_ppi_channel!(PPI_CH18, 18 => configurable); | 296 | impl_ppi_channel!(PPI_CH18, DPPIC, 18 => configurable); |
| 297 | impl_ppi_channel!(PPI_CH19, 19 => configurable); | 297 | impl_ppi_channel!(PPI_CH19, DPPIC, 19 => configurable); |
| 298 | impl_ppi_channel!(PPI_CH20, 20 => configurable); | 298 | impl_ppi_channel!(PPI_CH20, DPPIC, 20 => configurable); |
| 299 | impl_ppi_channel!(PPI_CH21, 21 => configurable); | 299 | impl_ppi_channel!(PPI_CH21, DPPIC, 21 => configurable); |
| 300 | impl_ppi_channel!(PPI_CH22, 22 => configurable); | 300 | impl_ppi_channel!(PPI_CH22, DPPIC, 22 => configurable); |
| 301 | impl_ppi_channel!(PPI_CH23, 23 => configurable); | 301 | impl_ppi_channel!(PPI_CH23, DPPIC, 23 => configurable); |
| 302 | impl_ppi_channel!(PPI_CH24, 24 => configurable); | 302 | impl_ppi_channel!(PPI_CH24, DPPIC, 24 => configurable); |
| 303 | impl_ppi_channel!(PPI_CH25, 25 => configurable); | 303 | impl_ppi_channel!(PPI_CH25, DPPIC, 25 => configurable); |
| 304 | impl_ppi_channel!(PPI_CH26, 26 => configurable); | 304 | impl_ppi_channel!(PPI_CH26, DPPIC, 26 => configurable); |
| 305 | impl_ppi_channel!(PPI_CH27, 27 => configurable); | 305 | impl_ppi_channel!(PPI_CH27, DPPIC, 27 => configurable); |
| 306 | impl_ppi_channel!(PPI_CH28, 28 => configurable); | 306 | impl_ppi_channel!(PPI_CH28, DPPIC, 28 => configurable); |
| 307 | impl_ppi_channel!(PPI_CH29, 29 => configurable); | 307 | impl_ppi_channel!(PPI_CH29, DPPIC, 29 => configurable); |
| 308 | impl_ppi_channel!(PPI_CH30, 30 => configurable); | 308 | impl_ppi_channel!(PPI_CH30, DPPIC, 30 => configurable); |
| 309 | impl_ppi_channel!(PPI_CH31, 31 => configurable); | 309 | impl_ppi_channel!(PPI_CH31, DPPIC, 31 => configurable); |
| 310 | |||
| 311 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 312 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 313 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 314 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 315 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 316 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 310 | 317 | ||
| 311 | impl_radio!(RADIO, RADIO, RADIO); | 318 | impl_radio!(RADIO, RADIO, RADIO); |
| 312 | 319 | ||
diff --git a/embassy-nrf/src/chips/nrf54l15_app.rs b/embassy-nrf/src/chips/nrf54l15_app.rs index 901c5e7fc..f58a74825 100644 --- a/embassy-nrf/src/chips/nrf54l15_app.rs +++ b/embassy-nrf/src/chips/nrf54l15_app.rs | |||
| @@ -200,13 +200,67 @@ pub mod pac { | |||
| 200 | 200 | ||
| 201 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. | 201 | /// The maximum buffer size that the EasyDMA can send/recv in one operation. |
| 202 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; | 202 | pub const EASY_DMA_SIZE: usize = (1 << 16) - 1; |
| 203 | //pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; | 203 | pub const FORCE_COPY_BUFFER_SIZE: usize = 1024; |
| 204 | 204 | ||
| 205 | // 1.5 MB NVM | 205 | // 1.5 MB NVM |
| 206 | #[allow(unused)] | 206 | #[allow(unused)] |
| 207 | pub const FLASH_SIZE: usize = 1536 * 1024; | 207 | pub const FLASH_SIZE: usize = 1536 * 1024; |
| 208 | 208 | ||
| 209 | embassy_hal_internal::peripherals! { | 209 | embassy_hal_internal::peripherals! { |
| 210 | // PPI | ||
| 211 | PPI00_CH0, | ||
| 212 | PPI00_CH1, | ||
| 213 | PPI00_CH2, | ||
| 214 | PPI00_CH3, | ||
| 215 | PPI00_CH4, | ||
| 216 | PPI00_CH5, | ||
| 217 | PPI00_CH6, | ||
| 218 | PPI00_CH7, | ||
| 219 | |||
| 220 | PPI20_CH0, | ||
| 221 | PPI20_CH1, | ||
| 222 | PPI20_CH2, | ||
| 223 | PPI20_CH3, | ||
| 224 | PPI20_CH4, | ||
| 225 | PPI20_CH5, | ||
| 226 | PPI20_CH6, | ||
| 227 | PPI20_CH7, | ||
| 228 | PPI20_CH8, | ||
| 229 | PPI20_CH9, | ||
| 230 | PPI20_CH10, | ||
| 231 | PPI20_CH11, | ||
| 232 | PPI20_CH12, | ||
| 233 | PPI20_CH13, | ||
| 234 | PPI20_CH14, | ||
| 235 | PPI20_CH15, | ||
| 236 | |||
| 237 | PPI30_CH0, | ||
| 238 | PPI30_CH1, | ||
| 239 | PPI30_CH2, | ||
| 240 | PPI30_CH3, | ||
| 241 | |||
| 242 | PPI00_GROUP0, | ||
| 243 | PPI00_GROUP1, | ||
| 244 | |||
| 245 | PPI20_GROUP0, | ||
| 246 | PPI20_GROUP1, | ||
| 247 | PPI20_GROUP2, | ||
| 248 | PPI20_GROUP3, | ||
| 249 | PPI20_GROUP4, | ||
| 250 | PPI20_GROUP5, | ||
| 251 | |||
| 252 | PPI30_GROUP0, | ||
| 253 | PPI30_GROUP1, | ||
| 254 | |||
| 255 | // Timers | ||
| 256 | TIMER00, | ||
| 257 | TIMER10, | ||
| 258 | TIMER20, | ||
| 259 | TIMER21, | ||
| 260 | TIMER22, | ||
| 261 | TIMER23, | ||
| 262 | TIMER24, | ||
| 263 | |||
| 210 | // GPIO port 0 | 264 | // GPIO port 0 |
| 211 | P0_00, | 265 | P0_00, |
| 212 | P0_01, | 266 | P0_01, |
| @@ -253,6 +307,11 @@ embassy_hal_internal::peripherals! { | |||
| 253 | RTC10, | 307 | RTC10, |
| 254 | RTC30, | 308 | RTC30, |
| 255 | 309 | ||
| 310 | // PWM | ||
| 311 | PWM20, | ||
| 312 | PWM21, | ||
| 313 | PWM22, | ||
| 314 | |||
| 256 | // SERIAL | 315 | // SERIAL |
| 257 | SERIAL00, | 316 | SERIAL00, |
| 258 | SERIAL20, | 317 | SERIAL20, |
| @@ -266,11 +325,6 @@ embassy_hal_internal::peripherals! { | |||
| 266 | // RADIO | 325 | // RADIO |
| 267 | RADIO, | 326 | RADIO, |
| 268 | 327 | ||
| 269 | // TIMER | ||
| 270 | TIMER00, | ||
| 271 | TIMER10, | ||
| 272 | TIMER20, | ||
| 273 | |||
| 274 | // PPI BRIDGE | 328 | // PPI BRIDGE |
| 275 | PPIB00, | 329 | PPIB00, |
| 276 | PPIB01, | 330 | PPIB01, |
| @@ -281,10 +335,24 @@ embassy_hal_internal::peripherals! { | |||
| 281 | PPIB22, | 335 | PPIB22, |
| 282 | PPIB30, | 336 | PPIB30, |
| 283 | 337 | ||
| 284 | // GPIOTE | 338 | // GPIOTE instances |
| 285 | GPIOTE20, | 339 | GPIOTE20, |
| 286 | GPIOTE30, | 340 | GPIOTE30, |
| 287 | 341 | ||
| 342 | // GPIOTE channels | ||
| 343 | GPIOTE20_CH0, | ||
| 344 | GPIOTE20_CH1, | ||
| 345 | GPIOTE20_CH2, | ||
| 346 | GPIOTE20_CH3, | ||
| 347 | GPIOTE20_CH4, | ||
| 348 | GPIOTE20_CH5, | ||
| 349 | GPIOTE20_CH6, | ||
| 350 | GPIOTE20_CH7, | ||
| 351 | GPIOTE30_CH0, | ||
| 352 | GPIOTE30_CH1, | ||
| 353 | GPIOTE30_CH2, | ||
| 354 | GPIOTE30_CH3, | ||
| 355 | |||
| 288 | // CRACEN | 356 | // CRACEN |
| 289 | CRACEN, | 357 | CRACEN, |
| 290 | 358 | ||
| @@ -311,6 +379,13 @@ impl_pin!(P0_03, 0, 3); | |||
| 311 | impl_pin!(P0_04, 0, 4); | 379 | impl_pin!(P0_04, 0, 4); |
| 312 | impl_pin!(P0_05, 0, 5); | 380 | impl_pin!(P0_05, 0, 5); |
| 313 | impl_pin!(P0_06, 0, 6); | 381 | impl_pin!(P0_06, 0, 6); |
| 382 | impl_gpiote_pin!(P0_00, GPIOTE30); | ||
| 383 | impl_gpiote_pin!(P0_01, GPIOTE30); | ||
| 384 | impl_gpiote_pin!(P0_02, GPIOTE30); | ||
| 385 | impl_gpiote_pin!(P0_03, GPIOTE30); | ||
| 386 | impl_gpiote_pin!(P0_04, GPIOTE30); | ||
| 387 | impl_gpiote_pin!(P0_05, GPIOTE30); | ||
| 388 | impl_gpiote_pin!(P0_06, GPIOTE30); | ||
| 314 | 389 | ||
| 315 | impl_pin!(P1_00, 1, 0); | 390 | impl_pin!(P1_00, 1, 0); |
| 316 | impl_pin!(P1_01, 1, 1); | 391 | impl_pin!(P1_01, 1, 1); |
| @@ -330,6 +405,24 @@ impl_pin!(P1_14, 1, 14); | |||
| 330 | impl_pin!(P1_15, 1, 15); | 405 | impl_pin!(P1_15, 1, 15); |
| 331 | impl_pin!(P1_16, 1, 16); | 406 | impl_pin!(P1_16, 1, 16); |
| 332 | 407 | ||
| 408 | impl_gpiote_pin!(P1_00, GPIOTE20); | ||
| 409 | impl_gpiote_pin!(P1_01, GPIOTE20); | ||
| 410 | impl_gpiote_pin!(P1_02, GPIOTE20); | ||
| 411 | impl_gpiote_pin!(P1_03, GPIOTE20); | ||
| 412 | impl_gpiote_pin!(P1_04, GPIOTE20); | ||
| 413 | impl_gpiote_pin!(P1_05, GPIOTE20); | ||
| 414 | impl_gpiote_pin!(P1_06, GPIOTE20); | ||
| 415 | impl_gpiote_pin!(P1_07, GPIOTE20); | ||
| 416 | impl_gpiote_pin!(P1_08, GPIOTE20); | ||
| 417 | impl_gpiote_pin!(P1_09, GPIOTE20); | ||
| 418 | impl_gpiote_pin!(P1_10, GPIOTE20); | ||
| 419 | impl_gpiote_pin!(P1_11, GPIOTE20); | ||
| 420 | impl_gpiote_pin!(P1_12, GPIOTE20); | ||
| 421 | impl_gpiote_pin!(P1_13, GPIOTE20); | ||
| 422 | impl_gpiote_pin!(P1_14, GPIOTE20); | ||
| 423 | impl_gpiote_pin!(P1_15, GPIOTE20); | ||
| 424 | impl_gpiote_pin!(P1_16, GPIOTE20); | ||
| 425 | |||
| 333 | impl_pin!(P2_00, 2, 0); | 426 | impl_pin!(P2_00, 2, 0); |
| 334 | impl_pin!(P2_01, 2, 1); | 427 | impl_pin!(P2_01, 2, 1); |
| 335 | impl_pin!(P2_02, 2, 2); | 428 | impl_pin!(P2_02, 2, 2); |
| @@ -351,6 +444,128 @@ impl_wdt!(WDT, WDT31, WDT31, 0); | |||
| 351 | impl_wdt!(WDT0, WDT31, WDT31, 0); | 444 | impl_wdt!(WDT0, WDT31, WDT31, 0); |
| 352 | #[cfg(feature = "_s")] | 445 | #[cfg(feature = "_s")] |
| 353 | impl_wdt!(WDT1, WDT30, WDT30, 1); | 446 | impl_wdt!(WDT1, WDT30, WDT30, 1); |
| 447 | // DPPI00 channels | ||
| 448 | impl_ppi_channel!(PPI00_CH0, DPPIC00, 0 => configurable); | ||
| 449 | impl_ppi_channel!(PPI00_CH1, DPPIC00, 1 => configurable); | ||
| 450 | impl_ppi_channel!(PPI00_CH2, DPPIC00, 2 => configurable); | ||
| 451 | impl_ppi_channel!(PPI00_CH3, DPPIC00, 3 => configurable); | ||
| 452 | impl_ppi_channel!(PPI00_CH4, DPPIC00, 4 => configurable); | ||
| 453 | impl_ppi_channel!(PPI00_CH5, DPPIC00, 5 => configurable); | ||
| 454 | impl_ppi_channel!(PPI00_CH6, DPPIC00, 6 => configurable); | ||
| 455 | impl_ppi_channel!(PPI00_CH7, DPPIC00, 7 => configurable); | ||
| 456 | |||
| 457 | // DPPI20 channels | ||
| 458 | impl_ppi_channel!(PPI20_CH0, DPPIC20, 0 => configurable); | ||
| 459 | impl_ppi_channel!(PPI20_CH1, DPPIC20, 1 => configurable); | ||
| 460 | impl_ppi_channel!(PPI20_CH2, DPPIC20, 2 => configurable); | ||
| 461 | impl_ppi_channel!(PPI20_CH3, DPPIC20, 3 => configurable); | ||
| 462 | impl_ppi_channel!(PPI20_CH4, DPPIC20, 4 => configurable); | ||
| 463 | impl_ppi_channel!(PPI20_CH5, DPPIC20, 5 => configurable); | ||
| 464 | impl_ppi_channel!(PPI20_CH6, DPPIC20, 6 => configurable); | ||
| 465 | impl_ppi_channel!(PPI20_CH7, DPPIC20, 7 => configurable); | ||
| 466 | impl_ppi_channel!(PPI20_CH8, DPPIC20, 8 => configurable); | ||
| 467 | impl_ppi_channel!(PPI20_CH9, DPPIC20, 9 => configurable); | ||
| 468 | impl_ppi_channel!(PPI20_CH10, DPPIC20, 10 => configurable); | ||
| 469 | impl_ppi_channel!(PPI20_CH11, DPPIC20, 11 => configurable); | ||
| 470 | impl_ppi_channel!(PPI20_CH12, DPPIC20, 12 => configurable); | ||
| 471 | impl_ppi_channel!(PPI20_CH13, DPPIC20, 13 => configurable); | ||
| 472 | impl_ppi_channel!(PPI20_CH14, DPPIC20, 14 => configurable); | ||
| 473 | impl_ppi_channel!(PPI20_CH15, DPPIC20, 15 => configurable); | ||
| 474 | |||
| 475 | // DPPI30 channels | ||
| 476 | impl_ppi_channel!(PPI30_CH0, DPPIC30, 0 => configurable); | ||
| 477 | impl_ppi_channel!(PPI30_CH1, DPPIC30, 1 => configurable); | ||
| 478 | impl_ppi_channel!(PPI30_CH2, DPPIC30, 2 => configurable); | ||
| 479 | impl_ppi_channel!(PPI30_CH3, DPPIC30, 3 => configurable); | ||
| 480 | |||
| 481 | // DPPI00 groups | ||
| 482 | impl_ppi_group!(PPI00_GROUP0, DPPIC00, 0); | ||
| 483 | impl_ppi_group!(PPI00_GROUP1, DPPIC00, 1); | ||
| 484 | |||
| 485 | // DPPI20 groups | ||
| 486 | impl_ppi_group!(PPI20_GROUP0, DPPIC20, 0); | ||
| 487 | impl_ppi_group!(PPI20_GROUP1, DPPIC20, 1); | ||
| 488 | impl_ppi_group!(PPI20_GROUP2, DPPIC20, 2); | ||
| 489 | impl_ppi_group!(PPI20_GROUP3, DPPIC20, 3); | ||
| 490 | impl_ppi_group!(PPI20_GROUP4, DPPIC20, 4); | ||
| 491 | impl_ppi_group!(PPI20_GROUP5, DPPIC20, 5); | ||
| 492 | |||
| 493 | // DPPI30 groups | ||
| 494 | impl_ppi_group!(PPI30_GROUP0, DPPIC30, 0); | ||
| 495 | impl_ppi_group!(PPI30_GROUP1, DPPIC30, 1); | ||
| 496 | |||
| 497 | // impl_ppi_channel!(PPI10_CH0, pac::DPPIC10, 0 => static); | ||
| 498 | // impl_ppi_group!(PPI10_GROUP0, pac::DPPIC10, 0); | ||
| 499 | |||
| 500 | impl_timer!(TIMER00, TIMER00, TIMER00); | ||
| 501 | impl_timer!(TIMER10, TIMER10, TIMER10); | ||
| 502 | impl_timer!(TIMER20, TIMER20, TIMER20); | ||
| 503 | impl_timer!(TIMER21, TIMER21, TIMER21); | ||
| 504 | impl_timer!(TIMER22, TIMER22, TIMER22); | ||
| 505 | impl_timer!(TIMER23, TIMER23, TIMER23); | ||
| 506 | impl_timer!(TIMER24, TIMER24, TIMER24); | ||
| 507 | |||
| 508 | impl_twim!(SERIAL20, TWIM20, SERIAL20); | ||
| 509 | impl_twim!(SERIAL21, TWIM21, SERIAL21); | ||
| 510 | impl_twim!(SERIAL22, TWIM22, SERIAL22); | ||
| 511 | impl_twim!(SERIAL30, TWIM30, SERIAL30); | ||
| 512 | |||
| 513 | impl_twis!(SERIAL20, TWIS20, SERIAL20); | ||
| 514 | impl_twis!(SERIAL21, TWIS21, SERIAL21); | ||
| 515 | impl_twis!(SERIAL22, TWIS22, SERIAL22); | ||
| 516 | impl_twis!(SERIAL30, TWIS30, SERIAL30); | ||
| 517 | |||
| 518 | impl_pwm!(PWM20, PWM20, PWM20); | ||
| 519 | impl_pwm!(PWM21, PWM21, PWM21); | ||
| 520 | impl_pwm!(PWM22, PWM22, PWM22); | ||
| 521 | |||
| 522 | #[cfg(feature = "_s")] | ||
| 523 | impl_spim!( | ||
| 524 | SERIAL00, | ||
| 525 | SPIM00, | ||
| 526 | SERIAL00, | ||
| 527 | match pac::OSCILLATORS_S.pll().currentfreq().read().currentfreq() { | ||
| 528 | pac::oscillators::vals::Currentfreq::CK128M => 128_000_000, | ||
| 529 | pac::oscillators::vals::Currentfreq::CK64M => 64_000_000, | ||
| 530 | _ => unreachable!(), | ||
| 531 | } | ||
| 532 | ); | ||
| 533 | #[cfg(feature = "_ns")] | ||
| 534 | impl_spim!( | ||
| 535 | SERIAL00, | ||
| 536 | SPIM00, | ||
| 537 | SERIAL00, | ||
| 538 | match pac::OSCILLATORS_NS.pll().currentfreq().read().currentfreq() { | ||
| 539 | pac::oscillators::vals::Currentfreq::CK128M => 128_000_000, | ||
| 540 | pac::oscillators::vals::Currentfreq::CK64M => 64_000_000, | ||
| 541 | _ => unreachable!(), | ||
| 542 | } | ||
| 543 | ); | ||
| 544 | impl_spim!(SERIAL20, SPIM20, SERIAL20, 16_000_000); | ||
| 545 | impl_spim!(SERIAL21, SPIM21, SERIAL21, 16_000_000); | ||
| 546 | impl_spim!(SERIAL22, SPIM22, SERIAL22, 16_000_000); | ||
| 547 | impl_spim!(SERIAL30, SPIM30, SERIAL30, 16_000_000); | ||
| 548 | |||
| 549 | impl_spis!(SERIAL20, SPIS20, SERIAL20); | ||
| 550 | impl_spis!(SERIAL21, SPIS21, SERIAL21); | ||
| 551 | impl_spis!(SERIAL22, SPIS22, SERIAL22); | ||
| 552 | impl_spis!(SERIAL30, SPIS30, SERIAL30); | ||
| 553 | |||
| 554 | impl_uarte!(SERIAL00, UARTE00, SERIAL00); | ||
| 555 | impl_uarte!(SERIAL20, UARTE20, SERIAL20); | ||
| 556 | impl_uarte!(SERIAL21, UARTE21, SERIAL21); | ||
| 557 | impl_uarte!(SERIAL22, UARTE22, SERIAL22); | ||
| 558 | impl_uarte!(SERIAL30, UARTE30, SERIAL30); | ||
| 559 | |||
| 560 | // NB: SAADC uses "pin" abstraction, not "AIN" | ||
| 561 | impl_saadc_input!(P1_04, 1, 4); | ||
| 562 | impl_saadc_input!(P1_05, 1, 5); | ||
| 563 | impl_saadc_input!(P1_06, 1, 6); | ||
| 564 | impl_saadc_input!(P1_07, 1, 7); | ||
| 565 | impl_saadc_input!(P1_11, 1, 11); | ||
| 566 | impl_saadc_input!(P1_12, 1, 12); | ||
| 567 | impl_saadc_input!(P1_13, 1, 13); | ||
| 568 | impl_saadc_input!(P1_14, 1, 14); | ||
| 354 | 569 | ||
| 355 | embassy_hal_internal::interrupt_mod!( | 570 | embassy_hal_internal::interrupt_mod!( |
| 356 | SWI00, | 571 | SWI00, |
diff --git a/embassy-nrf/src/chips/nrf9120.rs b/embassy-nrf/src/chips/nrf9120.rs index 5aee19d97..e9f313fef 100644 --- a/embassy-nrf/src/chips/nrf9120.rs +++ b/embassy-nrf/src/chips/nrf9120.rs | |||
| @@ -314,22 +314,29 @@ impl_pin!(P0_29, 0, 29); | |||
| 314 | impl_pin!(P0_30, 0, 30); | 314 | impl_pin!(P0_30, 0, 30); |
| 315 | impl_pin!(P0_31, 0, 31); | 315 | impl_pin!(P0_31, 0, 31); |
| 316 | 316 | ||
| 317 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 317 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 318 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 318 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 319 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 319 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 320 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 320 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 321 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 321 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 322 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 322 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 323 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 323 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 324 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 324 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 325 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 325 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 326 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 326 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 327 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 327 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 328 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 328 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 329 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 329 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 330 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 330 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 331 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 331 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 332 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 332 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 333 | |||
| 334 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 335 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 336 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 337 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 338 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 339 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 333 | 340 | ||
| 334 | impl_saadc_input!(P0_13, ANALOG_INPUT0); | 341 | impl_saadc_input!(P0_13, ANALOG_INPUT0); |
| 335 | impl_saadc_input!(P0_14, ANALOG_INPUT1); | 342 | impl_saadc_input!(P0_14, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs index 64aec217c..4c6f055dd 100644 --- a/embassy-nrf/src/chips/nrf9160.rs +++ b/embassy-nrf/src/chips/nrf9160.rs | |||
| @@ -314,22 +314,29 @@ impl_pin!(P0_29, 0, 29); | |||
| 314 | impl_pin!(P0_30, 0, 30); | 314 | impl_pin!(P0_30, 0, 30); |
| 315 | impl_pin!(P0_31, 0, 31); | 315 | impl_pin!(P0_31, 0, 31); |
| 316 | 316 | ||
| 317 | impl_ppi_channel!(PPI_CH0, 0 => configurable); | 317 | impl_ppi_channel!(PPI_CH0, DPPIC, 0 => configurable); |
| 318 | impl_ppi_channel!(PPI_CH1, 1 => configurable); | 318 | impl_ppi_channel!(PPI_CH1, DPPIC, 1 => configurable); |
| 319 | impl_ppi_channel!(PPI_CH2, 2 => configurable); | 319 | impl_ppi_channel!(PPI_CH2, DPPIC, 2 => configurable); |
| 320 | impl_ppi_channel!(PPI_CH3, 3 => configurable); | 320 | impl_ppi_channel!(PPI_CH3, DPPIC, 3 => configurable); |
| 321 | impl_ppi_channel!(PPI_CH4, 4 => configurable); | 321 | impl_ppi_channel!(PPI_CH4, DPPIC, 4 => configurable); |
| 322 | impl_ppi_channel!(PPI_CH5, 5 => configurable); | 322 | impl_ppi_channel!(PPI_CH5, DPPIC, 5 => configurable); |
| 323 | impl_ppi_channel!(PPI_CH6, 6 => configurable); | 323 | impl_ppi_channel!(PPI_CH6, DPPIC, 6 => configurable); |
| 324 | impl_ppi_channel!(PPI_CH7, 7 => configurable); | 324 | impl_ppi_channel!(PPI_CH7, DPPIC, 7 => configurable); |
| 325 | impl_ppi_channel!(PPI_CH8, 8 => configurable); | 325 | impl_ppi_channel!(PPI_CH8, DPPIC, 8 => configurable); |
| 326 | impl_ppi_channel!(PPI_CH9, 9 => configurable); | 326 | impl_ppi_channel!(PPI_CH9, DPPIC, 9 => configurable); |
| 327 | impl_ppi_channel!(PPI_CH10, 10 => configurable); | 327 | impl_ppi_channel!(PPI_CH10, DPPIC, 10 => configurable); |
| 328 | impl_ppi_channel!(PPI_CH11, 11 => configurable); | 328 | impl_ppi_channel!(PPI_CH11, DPPIC, 11 => configurable); |
| 329 | impl_ppi_channel!(PPI_CH12, 12 => configurable); | 329 | impl_ppi_channel!(PPI_CH12, DPPIC, 12 => configurable); |
| 330 | impl_ppi_channel!(PPI_CH13, 13 => configurable); | 330 | impl_ppi_channel!(PPI_CH13, DPPIC, 13 => configurable); |
| 331 | impl_ppi_channel!(PPI_CH14, 14 => configurable); | 331 | impl_ppi_channel!(PPI_CH14, DPPIC, 14 => configurable); |
| 332 | impl_ppi_channel!(PPI_CH15, 15 => configurable); | 332 | impl_ppi_channel!(PPI_CH15, DPPIC, 15 => configurable); |
| 333 | |||
| 334 | impl_ppi_group!(PPI_GROUP0, DPPIC, 0); | ||
| 335 | impl_ppi_group!(PPI_GROUP1, DPPIC, 1); | ||
| 336 | impl_ppi_group!(PPI_GROUP2, DPPIC, 2); | ||
| 337 | impl_ppi_group!(PPI_GROUP3, DPPIC, 3); | ||
| 338 | impl_ppi_group!(PPI_GROUP4, DPPIC, 4); | ||
| 339 | impl_ppi_group!(PPI_GROUP5, DPPIC, 5); | ||
| 333 | 340 | ||
| 334 | impl_saadc_input!(P0_13, ANALOG_INPUT0); | 341 | impl_saadc_input!(P0_13, ANALOG_INPUT0); |
| 335 | impl_saadc_input!(P0_14, ANALOG_INPUT1); | 342 | impl_saadc_input!(P0_14, ANALOG_INPUT1); |
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 7ed3a7927..43d1b9cb2 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -585,7 +585,6 @@ impl SealedPin for AnyPin { | |||
| 585 | // ==================== | 585 | // ==================== |
| 586 | 586 | ||
| 587 | #[cfg(not(feature = "_nrf51"))] | 587 | #[cfg(not(feature = "_nrf51"))] |
| 588 | #[cfg_attr(feature = "_nrf54l", allow(unused))] // TODO | ||
| 589 | pub(crate) trait PselBits { | 588 | pub(crate) trait PselBits { |
| 590 | fn psel_bits(&self) -> pac::shared::regs::Psel; | 589 | fn psel_bits(&self) -> pac::shared::regs::Psel; |
| 591 | } | 590 | } |
| @@ -602,7 +601,6 @@ impl<'a, P: Pin> PselBits for Option<Peri<'a, P>> { | |||
| 602 | } | 601 | } |
| 603 | 602 | ||
| 604 | #[cfg(not(feature = "_nrf51"))] | 603 | #[cfg(not(feature = "_nrf51"))] |
| 605 | #[cfg_attr(feature = "_nrf54l", allow(unused))] // TODO | ||
| 606 | pub(crate) const DISCONNECTED: Psel = Psel(1 << 31); | 604 | pub(crate) const DISCONNECTED: Psel = Psel(1 << 31); |
| 607 | 605 | ||
| 608 | #[cfg(not(feature = "_nrf51"))] | 606 | #[cfg(not(feature = "_nrf51"))] |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 3658657c0..060950132 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | //! GPIO task/event (GPIOTE) driver. | 1 | //! GPIO task/event (GPIOTE) driver. |
| 2 | #![macro_use] | ||
| 2 | 3 | ||
| 3 | use core::convert::Infallible; | 4 | use core::convert::Infallible; |
| 4 | use core::future::{Future, poll_fn}; | 5 | use core::future::{Future, poll_fn}; |
| @@ -7,7 +8,7 @@ use core::task::{Context, Poll}; | |||
| 7 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; | 8 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 9 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 10 | ||
| 10 | use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; | 11 | use crate::gpio::{AnyPin, Flex, Input, Level, Output, OutputDrive, Pin as GpioPin, Pull, SealedPin as _}; |
| 11 | use crate::interrupt::InterruptExt; | 12 | use crate::interrupt::InterruptExt; |
| 12 | #[cfg(not(feature = "_nrf51"))] | 13 | #[cfg(not(feature = "_nrf51"))] |
| 13 | use crate::pac::gpio::vals::Detectmode; | 14 | use crate::pac::gpio::vals::Detectmode; |
| @@ -19,13 +20,28 @@ use crate::{interrupt, pac, peripherals}; | |||
| 19 | #[cfg(feature = "_nrf51")] | 20 | #[cfg(feature = "_nrf51")] |
| 20 | /// Amount of GPIOTE channels in the chip. | 21 | /// Amount of GPIOTE channels in the chip. |
| 21 | const CHANNEL_COUNT: usize = 4; | 22 | const CHANNEL_COUNT: usize = 4; |
| 22 | #[cfg(not(feature = "_nrf51"))] | 23 | #[cfg(not(any(feature = "_nrf51", feature = "_nrf54l")))] |
| 23 | /// Amount of GPIOTE channels in the chip. | 24 | /// Amount of GPIOTE channels in the chip. |
| 24 | const CHANNEL_COUNT: usize = 8; | 25 | const CHANNEL_COUNT: usize = 8; |
| 25 | 26 | #[cfg(any(feature = "_nrf54l"))] | |
| 26 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 27 | /// Amount of GPIOTE channels in the chip. |
| 28 | const CHANNEL_COUNT: usize = 12; | ||
| 29 | /// Max channels per port | ||
| 30 | const CHANNELS_PER_PORT: usize = 8; | ||
| 31 | |||
| 32 | #[cfg(any( | ||
| 33 | feature = "nrf52833", | ||
| 34 | feature = "nrf52840", | ||
| 35 | feature = "_nrf5340", | ||
| 36 | feature = "_nrf54l" | ||
| 37 | ))] | ||
| 27 | const PIN_COUNT: usize = 48; | 38 | const PIN_COUNT: usize = 48; |
| 28 | #[cfg(not(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] | 39 | #[cfg(not(any( |
| 40 | feature = "nrf52833", | ||
| 41 | feature = "nrf52840", | ||
| 42 | feature = "_nrf5340", | ||
| 43 | feature = "_nrf54l" | ||
| 44 | )))] | ||
| 29 | const PIN_COUNT: usize = 32; | 45 | const PIN_COUNT: usize = 32; |
| 30 | 46 | ||
| 31 | #[allow(clippy::declare_interior_mutable_const)] | 47 | #[allow(clippy::declare_interior_mutable_const)] |
| @@ -54,18 +70,6 @@ pub enum OutputChannelPolarity { | |||
| 54 | Toggle, | 70 | Toggle, |
| 55 | } | 71 | } |
| 56 | 72 | ||
| 57 | fn regs() -> pac::gpiote::Gpiote { | ||
| 58 | cfg_if::cfg_if! { | ||
| 59 | if #[cfg(any(feature="nrf5340-app-s", feature="nrf9160-s", feature="nrf9120-s"))] { | ||
| 60 | pac::GPIOTE0 | ||
| 61 | } else if #[cfg(any(feature="nrf5340-app-ns", feature="nrf9160-ns", feature="nrf9120-ns"))] { | ||
| 62 | pac::GPIOTE1 | ||
| 63 | } else { | ||
| 64 | pac::GPIOTE | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | 73 | pub(crate) fn init(irq_prio: crate::interrupt::Priority) { |
| 70 | // no latched GPIO detect in nrf51. | 74 | // no latched GPIO detect in nrf51. |
| 71 | #[cfg(not(feature = "_nrf51"))] | 75 | #[cfg(not(feature = "_nrf51"))] |
| @@ -77,9 +81,9 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | |||
| 77 | 81 | ||
| 78 | for &p in ports { | 82 | for &p in ports { |
| 79 | // Enable latched detection | 83 | // Enable latched detection |
| 80 | #[cfg(feature = "_s")] | 84 | #[cfg(all(feature = "_s", not(feature = "_nrf54l")))] |
| 81 | p.detectmode_sec().write(|w| w.set_detectmode(Detectmode::LDETECT)); | 85 | p.detectmode_sec().write(|w| w.set_detectmode(Detectmode::LDETECT)); |
| 82 | #[cfg(not(feature = "_s"))] | 86 | #[cfg(any(not(feature = "_s"), all(feature = "_s", feature = "_nrf54l")))] |
| 83 | p.detectmode().write(|w| w.set_detectmode(Detectmode::LDETECT)); | 87 | p.detectmode().write(|w| w.set_detectmode(Detectmode::LDETECT)); |
| 84 | // Clear latch | 88 | // Clear latch |
| 85 | p.latch().write(|w| w.0 = 0xFFFFFFFF) | 89 | p.latch().write(|w| w.0 = 0xFFFFFFFF) |
| @@ -88,57 +92,136 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | |||
| 88 | 92 | ||
| 89 | // Enable interrupts | 93 | // Enable interrupts |
| 90 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] | 94 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] |
| 91 | let irq = interrupt::GPIOTE0; | 95 | let irqs = &[(pac::GPIOTE0, interrupt::GPIOTE0)]; |
| 92 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] | 96 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] |
| 93 | let irq = interrupt::GPIOTE1; | 97 | let irqs = &[(pac::GPIOTE1, interrupt::GPIOTE1)]; |
| 94 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] | 98 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] |
| 95 | let irq = interrupt::GPIOTE; | 99 | let irqs = &[(pac::GPIOTE, interrupt::GPIOTE)]; |
| 100 | #[cfg(any(feature = "_nrf54l"))] | ||
| 101 | let irqs = &[ | ||
| 102 | #[cfg(feature = "_s")] | ||
| 103 | (pac::GPIOTE20, interrupt::GPIOTE20_0), | ||
| 104 | #[cfg(feature = "_s")] | ||
| 105 | (pac::GPIOTE30, interrupt::GPIOTE30_0), | ||
| 106 | #[cfg(feature = "_ns")] | ||
| 107 | (pac::GPIOTE20, interrupt::GPIOTE20_1), | ||
| 108 | #[cfg(feature = "_ns")] | ||
| 109 | (pac::GPIOTE30, interrupt::GPIOTE30_1), | ||
| 110 | ]; | ||
| 111 | |||
| 112 | for (inst, irq) in irqs { | ||
| 113 | irq.unpend(); | ||
| 114 | irq.set_priority(irq_prio); | ||
| 115 | unsafe { irq.enable() }; | ||
| 96 | 116 | ||
| 97 | irq.unpend(); | 117 | let g = inst; |
| 98 | irq.set_priority(irq_prio); | 118 | #[cfg(not(feature = "_nrf54l"))] |
| 99 | unsafe { irq.enable() }; | 119 | g.intenset(INTNUM).write(|w| w.set_port(true)); |
| 100 | 120 | ||
| 101 | let g = regs(); | 121 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] |
| 102 | g.intenset().write(|w| w.set_port(true)); | 122 | g.intenset(INTNUM).write(|w| w.set_port0nonsecure(true)); |
| 123 | |||
| 124 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | ||
| 125 | g.intenset(INTNUM).write(|w| w.set_port0secure(true)); | ||
| 126 | } | ||
| 103 | } | 127 | } |
| 104 | 128 | ||
| 129 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] | ||
| 130 | const INTNUM: usize = 1; | ||
| 131 | |||
| 132 | #[cfg(any(not(feature = "_nrf54l"), feature = "_s"))] | ||
| 133 | const INTNUM: usize = 0; | ||
| 134 | |||
| 105 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] | 135 | #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s", feature = "nrf9120-s"))] |
| 106 | #[cfg(feature = "rt")] | 136 | #[cfg(feature = "rt")] |
| 107 | #[interrupt] | 137 | #[interrupt] |
| 108 | fn GPIOTE0() { | 138 | fn GPIOTE0() { |
| 109 | unsafe { handle_gpiote_interrupt() }; | 139 | unsafe { handle_gpiote_interrupt(pac::GPIOTE0) }; |
| 110 | } | 140 | } |
| 111 | 141 | ||
| 112 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] | 142 | #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns", feature = "nrf9120-ns"))] |
| 113 | #[cfg(feature = "rt")] | 143 | #[cfg(feature = "rt")] |
| 114 | #[interrupt] | 144 | #[interrupt] |
| 115 | fn GPIOTE1() { | 145 | fn GPIOTE1() { |
| 116 | unsafe { handle_gpiote_interrupt() }; | 146 | unsafe { handle_gpiote_interrupt(pac::GPIOTE1) }; |
| 117 | } | 147 | } |
| 118 | 148 | ||
| 119 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] | 149 | #[cfg(any(feature = "_nrf51", feature = "_nrf52", feature = "nrf5340-net"))] |
| 120 | #[cfg(feature = "rt")] | 150 | #[cfg(feature = "rt")] |
| 121 | #[interrupt] | 151 | #[interrupt] |
| 122 | fn GPIOTE() { | 152 | fn GPIOTE() { |
| 123 | unsafe { handle_gpiote_interrupt() }; | 153 | info!("GPIOTE!"); |
| 154 | unsafe { handle_gpiote_interrupt(pac::GPIOTE) }; | ||
| 124 | } | 155 | } |
| 125 | 156 | ||
| 126 | unsafe fn handle_gpiote_interrupt() { | 157 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 127 | let g = regs(); | 158 | #[cfg(feature = "rt")] |
| 159 | #[interrupt] | ||
| 160 | fn GPIOTE20_0() { | ||
| 161 | info!("GPIOTE20_0!"); | ||
| 162 | unsafe { handle_gpiote_interrupt(pac::GPIOTE20) }; | ||
| 163 | } | ||
| 128 | 164 | ||
| 129 | for i in 0..CHANNEL_COUNT { | 165 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 166 | #[cfg(feature = "rt")] | ||
| 167 | #[interrupt] | ||
| 168 | fn GPIOTE30_0() { | ||
| 169 | info!("GPIOTE30_0!"); | ||
| 170 | unsafe { handle_gpiote_interrupt(pac::GPIOTE30) }; | ||
| 171 | } | ||
| 172 | |||
| 173 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] | ||
| 174 | #[cfg(feature = "rt")] | ||
| 175 | #[interrupt] | ||
| 176 | fn GPIOTE20_1() { | ||
| 177 | info!("GPIOTE20_1!"); | ||
| 178 | unsafe { handle_gpiote_interrupt(pac::GPIOTE20) }; | ||
| 179 | } | ||
| 180 | |||
| 181 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] | ||
| 182 | #[cfg(feature = "rt")] | ||
| 183 | #[interrupt] | ||
| 184 | fn GPIOTE30_1() { | ||
| 185 | info!("GPIOTE30_1!"); | ||
| 186 | unsafe { handle_gpiote_interrupt(pac::GPIOTE30) }; | ||
| 187 | } | ||
| 188 | |||
| 189 | unsafe fn handle_gpiote_interrupt(g: pac::gpiote::Gpiote) { | ||
| 190 | for c in 0..CHANNEL_COUNT { | ||
| 191 | let i = c % CHANNELS_PER_PORT; | ||
| 130 | if g.events_in(i).read() != 0 { | 192 | if g.events_in(i).read() != 0 { |
| 131 | g.intenclr().write(|w| w.0 = 1 << i); | 193 | info!("Clear IRQ {} waker {}", INTNUM, c); |
| 132 | CHANNEL_WAKERS[i].wake(); | 194 | g.intenclr(INTNUM).write(|w| w.0 = 1 << i); |
| 195 | CHANNEL_WAKERS[c].wake(); | ||
| 133 | } | 196 | } |
| 134 | } | 197 | } |
| 135 | 198 | ||
| 136 | if g.events_port().read() != 0 { | 199 | #[cfg(not(feature = "_nrf54l"))] |
| 137 | g.events_port().write_value(0); | 200 | let eport = g.events_port(0); |
| 138 | 201 | ||
| 139 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 202 | #[cfg(all(feature = "_nrf54l", feature = "_ns"))] |
| 203 | let eport = g.events_port(0).nonsecure(); | ||
| 204 | |||
| 205 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | ||
| 206 | let eport = g.events_port(0).secure(); | ||
| 207 | |||
| 208 | if eport.read() != 0 { | ||
| 209 | eport.write_value(0); | ||
| 210 | |||
| 211 | #[cfg(any( | ||
| 212 | feature = "nrf52833", | ||
| 213 | feature = "nrf52840", | ||
| 214 | feature = "_nrf5340", | ||
| 215 | feature = "_nrf54l" | ||
| 216 | ))] | ||
| 140 | let ports = &[pac::P0, pac::P1]; | 217 | let ports = &[pac::P0, pac::P1]; |
| 141 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))] | 218 | #[cfg(not(any( |
| 219 | feature = "_nrf51", | ||
| 220 | feature = "nrf52833", | ||
| 221 | feature = "nrf52840", | ||
| 222 | feature = "_nrf5340", | ||
| 223 | feature = "_nrf54l" | ||
| 224 | )))] | ||
| 142 | let ports = &[pac::P0]; | 225 | let ports = &[pac::P0]; |
| 143 | #[cfg(feature = "_nrf51")] | 226 | #[cfg(feature = "_nrf51")] |
| 144 | let ports = &[pac::GPIO]; | 227 | let ports = &[pac::GPIO]; |
| @@ -162,9 +245,14 @@ unsafe fn handle_gpiote_interrupt() { | |||
| 162 | 245 | ||
| 163 | #[cfg(not(feature = "_nrf51"))] | 246 | #[cfg(not(feature = "_nrf51"))] |
| 164 | for (port, &p) in ports.iter().enumerate() { | 247 | for (port, &p) in ports.iter().enumerate() { |
| 248 | info!("Interrupt port {}", port); | ||
| 165 | let bits = p.latch().read().0; | 249 | let bits = p.latch().read().0; |
| 166 | for pin in BitIter(bits) { | 250 | for pin in BitIter(bits) { |
| 167 | p.pin_cnf(pin as usize).modify(|w| w.set_sense(Sense::DISABLED)); | 251 | p.pin_cnf(pin as usize).modify(|w| w.set_sense(Sense::DISABLED)); |
| 252 | |||
| 253 | let w = port * 32 + pin as usize; | ||
| 254 | |||
| 255 | info!("Interrupt pin {}, waker {}", pin as usize, w); | ||
| 168 | PORT_WAKERS[port * 32 + pin as usize].wake(); | 256 | PORT_WAKERS[port * 32 + pin as usize].wake(); |
| 169 | } | 257 | } |
| 170 | p.latch().write(|w| w.0 = bits); | 258 | p.latch().write(|w| w.0 = bits); |
| @@ -207,19 +295,43 @@ impl InputChannel<'static> { | |||
| 207 | 295 | ||
| 208 | impl<'d> Drop for InputChannel<'d> { | 296 | impl<'d> Drop for InputChannel<'d> { |
| 209 | fn drop(&mut self) { | 297 | fn drop(&mut self) { |
| 210 | let g = regs(); | 298 | let g = self.ch.regs(); |
| 211 | let num = self.ch.number(); | 299 | let num = self.ch.number(); |
| 212 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); | 300 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); |
| 213 | g.intenclr().write(|w| w.0 = 1 << num); | 301 | g.intenclr(INTNUM).write(|w| w.0 = 1 << num); |
| 214 | } | 302 | } |
| 215 | } | 303 | } |
| 216 | 304 | ||
| 217 | impl<'d> InputChannel<'d> { | 305 | impl<'d> InputChannel<'d> { |
| 218 | /// Create a new GPIOTE input channel driver. | 306 | /// Create a new GPIOTE input channel driver. |
| 219 | pub fn new(ch: Peri<'d, impl Channel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { | 307 | #[cfg(feature = "_nrf54l")] |
| 220 | let g = regs(); | 308 | pub fn new<C: Channel, T: GpiotePin<Instance = C::Instance>>( |
| 221 | let num = ch.number(); | 309 | ch: Peri<'d, C>, |
| 310 | pin: Peri<'d, T>, | ||
| 311 | pull: Pull, | ||
| 312 | polarity: InputChannelPolarity, | ||
| 313 | ) -> Self { | ||
| 314 | let pin = Input::new(pin, pull); | ||
| 315 | let ch = ch.into(); | ||
| 316 | Self::new_inner(ch, pin, polarity) | ||
| 317 | } | ||
| 222 | 318 | ||
| 319 | /// Create a new GPIOTE output channel driver. | ||
| 320 | #[cfg(not(feature = "_nrf54l"))] | ||
| 321 | pub fn new<C: Channel, T: GpioPin>( | ||
| 322 | ch: Peri<'d, C>, | ||
| 323 | pin: Peri<'d, T>, | ||
| 324 | pull: Pull, | ||
| 325 | polarity: InputChannelPolarity, | ||
| 326 | ) -> Self { | ||
| 327 | let pin = Input::new(pin, pull); | ||
| 328 | let ch = ch.into(); | ||
| 329 | Self::new_inner(ch, pin, polarity) | ||
| 330 | } | ||
| 331 | |||
| 332 | fn new_inner(ch: Peri<'d, AnyChannel>, pin: Input<'d>, polarity: InputChannelPolarity) -> Self { | ||
| 333 | let g = ch.regs(); | ||
| 334 | let num = ch.number(); | ||
| 223 | g.config(num).write(|w| { | 335 | g.config(num).write(|w| { |
| 224 | w.set_mode(Mode::EVENT); | 336 | w.set_mode(Mode::EVENT); |
| 225 | match polarity { | 337 | match polarity { |
| @@ -228,30 +340,38 @@ impl<'d> InputChannel<'d> { | |||
| 228 | InputChannelPolarity::None => w.set_polarity(Polarity::NONE), | 340 | InputChannelPolarity::None => w.set_polarity(Polarity::NONE), |
| 229 | InputChannelPolarity::Toggle => w.set_polarity(Polarity::TOGGLE), | 341 | InputChannelPolarity::Toggle => w.set_polarity(Polarity::TOGGLE), |
| 230 | }; | 342 | }; |
| 231 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))] | 343 | #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340",))] |
| 232 | w.set_port(match pin.pin.pin.port() { | 344 | w.set_port(match pin.pin.pin.port() { |
| 233 | crate::gpio::Port::Port0 => false, | 345 | crate::gpio::Port::Port0 => false, |
| 234 | crate::gpio::Port::Port1 => true, | 346 | crate::gpio::Port::Port1 => true, |
| 235 | }); | 347 | }); |
| 348 | #[cfg(any(feature = "_nrf54l"))] | ||
| 349 | w.set_port(match pin.pin.pin.port() { | ||
| 350 | crate::gpio::Port::Port0 => 0, | ||
| 351 | crate::gpio::Port::Port1 => 1, | ||
| 352 | crate::gpio::Port::Port2 => 2, | ||
| 353 | }); | ||
| 236 | w.set_psel(pin.pin.pin.pin()); | 354 | w.set_psel(pin.pin.pin.pin()); |
| 237 | }); | 355 | }); |
| 238 | 356 | ||
| 239 | g.events_in(num).write_value(0); | 357 | g.events_in(num).write_value(0); |
| 240 | 358 | ||
| 241 | InputChannel { ch: ch.into(), pin } | 359 | InputChannel { ch, pin } |
| 242 | } | 360 | } |
| 243 | 361 | ||
| 244 | /// Asynchronously wait for an event in this channel. | 362 | /// Asynchronously wait for an event in this channel. |
| 245 | pub async fn wait(&self) { | 363 | pub async fn wait(&self) { |
| 246 | let g = regs(); | 364 | let g = self.ch.regs(); |
| 247 | let num = self.ch.number(); | 365 | let num = self.ch.number(); |
| 366 | let waker = self.ch.waker(); | ||
| 248 | 367 | ||
| 249 | // Enable interrupt | 368 | // Enable interrupt |
| 250 | g.events_in(num).write_value(0); | 369 | g.events_in(num).write_value(0); |
| 251 | g.intenset().write(|w| w.0 = 1 << num); | 370 | g.intenset(INTNUM).write(|w| w.0 = 1 << num); |
| 252 | 371 | ||
| 253 | poll_fn(|cx| { | 372 | poll_fn(|cx| { |
| 254 | CHANNEL_WAKERS[num].register(cx.waker()); | 373 | info!("Waiting for channel waker {}", num); |
| 374 | CHANNEL_WAKERS[waker].register(cx.waker()); | ||
| 255 | 375 | ||
| 256 | if g.events_in(num).read() != 0 { | 376 | if g.events_in(num).read() != 0 { |
| 257 | Poll::Ready(()) | 377 | Poll::Ready(()) |
| @@ -269,7 +389,7 @@ impl<'d> InputChannel<'d> { | |||
| 269 | 389 | ||
| 270 | /// Returns the IN event, for use with PPI. | 390 | /// Returns the IN event, for use with PPI. |
| 271 | pub fn event_in(&self) -> Event<'d> { | 391 | pub fn event_in(&self) -> Event<'d> { |
| 272 | let g = regs(); | 392 | let g = self.ch.regs(); |
| 273 | Event::from_reg(g.events_in(self.ch.number())) | 393 | Event::from_reg(g.events_in(self.ch.number())) |
| 274 | } | 394 | } |
| 275 | } | 395 | } |
| @@ -291,17 +411,44 @@ impl OutputChannel<'static> { | |||
| 291 | 411 | ||
| 292 | impl<'d> Drop for OutputChannel<'d> { | 412 | impl<'d> Drop for OutputChannel<'d> { |
| 293 | fn drop(&mut self) { | 413 | fn drop(&mut self) { |
| 294 | let g = regs(); | 414 | let g = self.ch.regs(); |
| 295 | let num = self.ch.number(); | 415 | let num = self.ch.number(); |
| 296 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); | 416 | g.config(num).write(|w| w.set_mode(Mode::DISABLED)); |
| 297 | g.intenclr().write(|w| w.0 = 1 << num); | 417 | g.intenclr(INTNUM).write(|w| w.0 = 1 << num); |
| 298 | } | 418 | } |
| 299 | } | 419 | } |
| 300 | 420 | ||
| 301 | impl<'d> OutputChannel<'d> { | 421 | impl<'d> OutputChannel<'d> { |
| 302 | /// Create a new GPIOTE output channel driver. | 422 | /// Create a new GPIOTE output channel driver. |
| 303 | pub fn new(ch: Peri<'d, impl Channel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { | 423 | #[cfg(feature = "_nrf54l")] |
| 304 | let g = regs(); | 424 | pub fn new<C: Channel, T: GpiotePin<Instance = C::Instance>>( |
| 425 | ch: Peri<'d, C>, | ||
| 426 | pin: Peri<'d, T>, | ||
| 427 | initial_output: Level, | ||
| 428 | drive: OutputDrive, | ||
| 429 | polarity: OutputChannelPolarity, | ||
| 430 | ) -> Self { | ||
| 431 | let pin = Output::new(pin, initial_output, drive); | ||
| 432 | let ch = ch.into(); | ||
| 433 | Self::new_inner(ch, pin, polarity) | ||
| 434 | } | ||
| 435 | |||
| 436 | /// Create a new GPIOTE output channel driver. | ||
| 437 | #[cfg(not(feature = "_nrf54l"))] | ||
| 438 | pub fn new<C: Channel, T: GpioPin>( | ||
| 439 | ch: Peri<'d, C>, | ||
| 440 | pin: Peri<'d, T>, | ||
| 441 | initial_output: Level, | ||
| 442 | drive: OutputDrive, | ||
| 443 | polarity: OutputChannelPolarity, | ||
| 444 | ) -> Self { | ||
| 445 | let pin = Output::new(pin, initial_output, drive); | ||
| 446 | let ch = ch.into(); | ||
| 447 | Self::new_inner(ch, pin, polarity) | ||
| 448 | } | ||
| 449 | |||
| 450 | fn new_inner(ch: Peri<'d, AnyChannel>, pin: Output<'d>, polarity: OutputChannelPolarity) -> Self { | ||
| 451 | let g = ch.regs(); | ||
| 305 | let num = ch.number(); | 452 | let num = ch.number(); |
| 306 | 453 | ||
| 307 | g.config(num).write(|w| { | 454 | g.config(num).write(|w| { |
| @@ -320,52 +467,55 @@ impl<'d> OutputChannel<'d> { | |||
| 320 | crate::gpio::Port::Port0 => false, | 467 | crate::gpio::Port::Port0 => false, |
| 321 | crate::gpio::Port::Port1 => true, | 468 | crate::gpio::Port::Port1 => true, |
| 322 | }); | 469 | }); |
| 470 | #[cfg(any(feature = "_nrf54l"))] | ||
| 471 | w.set_port(match pin.pin.pin.port() { | ||
| 472 | crate::gpio::Port::Port0 => 0, | ||
| 473 | crate::gpio::Port::Port1 => 1, | ||
| 474 | crate::gpio::Port::Port2 => 2, | ||
| 475 | }); | ||
| 323 | w.set_psel(pin.pin.pin.pin()); | 476 | w.set_psel(pin.pin.pin.pin()); |
| 324 | }); | 477 | }); |
| 325 | 478 | ||
| 326 | OutputChannel { | 479 | OutputChannel { ch, _pin: pin } |
| 327 | ch: ch.into(), | ||
| 328 | _pin: pin, | ||
| 329 | } | ||
| 330 | } | 480 | } |
| 331 | 481 | ||
| 332 | /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle). | 482 | /// Triggers the OUT task (does the action as configured with task_out_polarity, defaults to Toggle). |
| 333 | pub fn out(&self) { | 483 | pub fn out(&self) { |
| 334 | let g = regs(); | 484 | let g = self.ch.regs(); |
| 335 | g.tasks_out(self.ch.number()).write_value(1); | 485 | g.tasks_out(self.ch.number()).write_value(1); |
| 336 | } | 486 | } |
| 337 | 487 | ||
| 338 | /// Triggers the SET task (set associated pin high). | 488 | /// Triggers the SET task (set associated pin high). |
| 339 | #[cfg(not(feature = "_nrf51"))] | 489 | #[cfg(not(feature = "_nrf51"))] |
| 340 | pub fn set(&self) { | 490 | pub fn set(&self) { |
| 341 | let g = regs(); | 491 | let g = self.ch.regs(); |
| 342 | g.tasks_set(self.ch.number()).write_value(1); | 492 | g.tasks_set(self.ch.number()).write_value(1); |
| 343 | } | 493 | } |
| 344 | 494 | ||
| 345 | /// Triggers the CLEAR task (set associated pin low). | 495 | /// Triggers the CLEAR task (set associated pin low). |
| 346 | #[cfg(not(feature = "_nrf51"))] | 496 | #[cfg(not(feature = "_nrf51"))] |
| 347 | pub fn clear(&self) { | 497 | pub fn clear(&self) { |
| 348 | let g = regs(); | 498 | let g = self.ch.regs(); |
| 349 | g.tasks_clr(self.ch.number()).write_value(1); | 499 | g.tasks_clr(self.ch.number()).write_value(1); |
| 350 | } | 500 | } |
| 351 | 501 | ||
| 352 | /// Returns the OUT task, for use with PPI. | 502 | /// Returns the OUT task, for use with PPI. |
| 353 | pub fn task_out(&self) -> Task<'d> { | 503 | pub fn task_out(&self) -> Task<'d> { |
| 354 | let g = regs(); | 504 | let g = self.ch.regs(); |
| 355 | Task::from_reg(g.tasks_out(self.ch.number())) | 505 | Task::from_reg(g.tasks_out(self.ch.number())) |
| 356 | } | 506 | } |
| 357 | 507 | ||
| 358 | /// Returns the CLR task, for use with PPI. | 508 | /// Returns the CLR task, for use with PPI. |
| 359 | #[cfg(not(feature = "_nrf51"))] | 509 | #[cfg(not(feature = "_nrf51"))] |
| 360 | pub fn task_clr(&self) -> Task<'d> { | 510 | pub fn task_clr(&self) -> Task<'d> { |
| 361 | let g = regs(); | 511 | let g = self.ch.regs(); |
| 362 | Task::from_reg(g.tasks_clr(self.ch.number())) | 512 | Task::from_reg(g.tasks_clr(self.ch.number())) |
| 363 | } | 513 | } |
| 364 | 514 | ||
| 365 | /// Returns the SET task, for use with PPI. | 515 | /// Returns the SET task, for use with PPI. |
| 366 | #[cfg(not(feature = "_nrf51"))] | 516 | #[cfg(not(feature = "_nrf51"))] |
| 367 | pub fn task_set(&self) -> Task<'d> { | 517 | pub fn task_set(&self) -> Task<'d> { |
| 368 | let g = regs(); | 518 | let g = self.ch.regs(); |
| 369 | Task::from_reg(g.tasks_set(self.ch.number())) | 519 | Task::from_reg(g.tasks_set(self.ch.number())) |
| 370 | } | 520 | } |
| 371 | } | 521 | } |
| @@ -395,6 +545,7 @@ impl<'a> Future for PortInputFuture<'a> { | |||
| 395 | type Output = (); | 545 | type Output = (); |
| 396 | 546 | ||
| 397 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | 547 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 548 | info!("register waker on {}", self.pin.port() as usize); | ||
| 398 | PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker()); | 549 | PORT_WAKERS[self.pin.pin_port() as usize].register(cx.waker()); |
| 399 | 550 | ||
| 400 | if self.pin.conf().read().sense() == Sense::DISABLED { | 551 | if self.pin.conf().read().sense() == Sense::DISABLED { |
| @@ -467,31 +618,52 @@ impl<'d> Flex<'d> { | |||
| 467 | PortInputFuture::new(self.pin.reborrow()).await | 618 | PortInputFuture::new(self.pin.reborrow()).await |
| 468 | } | 619 | } |
| 469 | } | 620 | } |
| 470 | |||
| 471 | // ======================= | 621 | // ======================= |
| 622 | // | ||
| 472 | 623 | ||
| 473 | trait SealedChannel {} | 624 | trait SealedChannel { |
| 625 | fn waker(&self) -> usize; | ||
| 626 | fn regs(&self) -> pac::gpiote::Gpiote; | ||
| 627 | } | ||
| 474 | 628 | ||
| 475 | /// GPIOTE channel trait. | 629 | /// GPIOTE channel trait. |
| 476 | /// | 630 | /// |
| 477 | /// Implemented by all GPIOTE channels. | 631 | /// Implemented by all GPIOTE channels. |
| 478 | #[allow(private_bounds)] | 632 | #[allow(private_bounds)] |
| 479 | pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static { | 633 | pub trait Channel: PeripheralType + SealedChannel + Into<AnyChannel> + Sized + 'static { |
| 634 | #[cfg(feature = "_nrf54l")] | ||
| 635 | /// GPIOTE instance this channel belongs to. | ||
| 636 | type Instance: GpioteInstance; | ||
| 480 | /// Get the channel number. | 637 | /// Get the channel number. |
| 481 | fn number(&self) -> usize; | 638 | fn number(&self) -> usize; |
| 482 | } | 639 | } |
| 483 | 640 | ||
| 484 | /// Type-erased channel. | 641 | struct AnyChannel { |
| 485 | /// | ||
| 486 | /// Obtained by calling `Channel::into()`. | ||
| 487 | /// | ||
| 488 | /// This allows using several channels in situations that might require | ||
| 489 | /// them to be the same type, like putting them in an array. | ||
| 490 | pub struct AnyChannel { | ||
| 491 | number: u8, | 642 | number: u8, |
| 643 | regs: pac::gpiote::Gpiote, | ||
| 644 | waker: u8, | ||
| 492 | } | 645 | } |
| 646 | |||
| 493 | impl_peripheral!(AnyChannel); | 647 | impl_peripheral!(AnyChannel); |
| 494 | impl SealedChannel for AnyChannel {} | 648 | |
| 649 | impl SealedChannel for AnyChannel { | ||
| 650 | fn waker(&self) -> usize { | ||
| 651 | self.waker as usize | ||
| 652 | } | ||
| 653 | |||
| 654 | fn regs(&self) -> pac::gpiote::Gpiote { | ||
| 655 | self.regs | ||
| 656 | } | ||
| 657 | } | ||
| 658 | |||
| 659 | #[cfg(feature = "_nrf54l")] | ||
| 660 | impl AnyChannel { | ||
| 661 | fn number(&self) -> usize { | ||
| 662 | self.number as usize | ||
| 663 | } | ||
| 664 | } | ||
| 665 | |||
| 666 | #[cfg(not(feature = "_nrf54l"))] | ||
| 495 | impl Channel for AnyChannel { | 667 | impl Channel for AnyChannel { |
| 496 | fn number(&self) -> usize { | 668 | fn number(&self) -> usize { |
| 497 | self.number as usize | 669 | self.number as usize |
| @@ -499,9 +671,19 @@ impl Channel for AnyChannel { | |||
| 499 | } | 671 | } |
| 500 | 672 | ||
| 501 | macro_rules! impl_channel { | 673 | macro_rules! impl_channel { |
| 502 | ($type:ident, $number:expr) => { | 674 | ($type:ident, $inst:ident, $number:expr, $waker:expr) => { |
| 503 | impl SealedChannel for peripherals::$type {} | 675 | impl SealedChannel for peripherals::$type { |
| 676 | fn waker(&self) -> usize { | ||
| 677 | $waker as usize | ||
| 678 | } | ||
| 679 | |||
| 680 | fn regs(&self) -> pac::gpiote::Gpiote { | ||
| 681 | pac::$inst | ||
| 682 | } | ||
| 683 | } | ||
| 504 | impl Channel for peripherals::$type { | 684 | impl Channel for peripherals::$type { |
| 685 | #[cfg(feature = "_nrf54l")] | ||
| 686 | type Instance = peripherals::$inst; | ||
| 505 | fn number(&self) -> usize { | 687 | fn number(&self) -> usize { |
| 506 | $number as usize | 688 | $number as usize |
| 507 | } | 689 | } |
| @@ -511,24 +693,97 @@ macro_rules! impl_channel { | |||
| 511 | fn from(val: peripherals::$type) -> Self { | 693 | fn from(val: peripherals::$type) -> Self { |
| 512 | Self { | 694 | Self { |
| 513 | number: val.number() as u8, | 695 | number: val.number() as u8, |
| 696 | waker: val.waker() as u8, | ||
| 697 | regs: val.regs(), | ||
| 514 | } | 698 | } |
| 515 | } | 699 | } |
| 516 | } | 700 | } |
| 517 | }; | 701 | }; |
| 518 | } | 702 | } |
| 519 | 703 | ||
| 520 | impl_channel!(GPIOTE_CH0, 0); | 704 | cfg_if::cfg_if! { |
| 521 | impl_channel!(GPIOTE_CH1, 1); | 705 | if #[cfg(feature = "_nrf54l")] { |
| 522 | impl_channel!(GPIOTE_CH2, 2); | 706 | trait SealedGpioteInstance {} |
| 523 | impl_channel!(GPIOTE_CH3, 3); | 707 | /// Represents a GPIOTE instance. |
| 524 | #[cfg(not(feature = "_nrf51"))] | 708 | #[allow(private_bounds)] |
| 525 | impl_channel!(GPIOTE_CH4, 4); | 709 | pub trait GpioteInstance: PeripheralType + SealedGpioteInstance + Sized + 'static {} |
| 526 | #[cfg(not(feature = "_nrf51"))] | 710 | |
| 527 | impl_channel!(GPIOTE_CH5, 5); | 711 | macro_rules! impl_gpiote { |
| 528 | #[cfg(not(feature = "_nrf51"))] | 712 | ($type:ident) => { |
| 529 | impl_channel!(GPIOTE_CH6, 6); | 713 | impl SealedGpioteInstance for peripherals::$type {} |
| 530 | #[cfg(not(feature = "_nrf51"))] | 714 | impl GpioteInstance for peripherals::$type {} |
| 531 | impl_channel!(GPIOTE_CH7, 7); | 715 | }; |
| 716 | } | ||
| 717 | |||
| 718 | pub(crate) trait SealedGpiotePin {} | ||
| 719 | |||
| 720 | /// Represents a GPIO pin that can be used with GPIOTE. | ||
| 721 | #[allow(private_bounds)] | ||
| 722 | pub trait GpiotePin: GpioPin + SealedGpiotePin { | ||
| 723 | /// The GPIOTE instance this pin belongs to. | ||
| 724 | type Instance: GpioteInstance; | ||
| 725 | } | ||
| 726 | |||
| 727 | macro_rules! impl_gpiote_pin { | ||
| 728 | ($type:ident, $inst:ident) => { | ||
| 729 | #[cfg(feature = "gpiote")] | ||
| 730 | impl crate::gpiote::SealedGpiotePin for peripherals::$type {} | ||
| 731 | #[cfg(feature = "gpiote")] | ||
| 732 | impl crate::gpiote::GpiotePin for peripherals::$type { | ||
| 733 | type Instance = peripherals::$inst; | ||
| 734 | } | ||
| 735 | }; | ||
| 736 | } | ||
| 737 | |||
| 738 | impl_gpiote!(GPIOTE20); | ||
| 739 | impl_gpiote!(GPIOTE30); | ||
| 740 | impl_channel!(GPIOTE20_CH0, GPIOTE20, 0, 0); | ||
| 741 | impl_channel!(GPIOTE20_CH1, GPIOTE20, 1, 1); | ||
| 742 | impl_channel!(GPIOTE20_CH2, GPIOTE20, 2, 2); | ||
| 743 | impl_channel!(GPIOTE20_CH3, GPIOTE20, 3, 3); | ||
| 744 | impl_channel!(GPIOTE20_CH4, GPIOTE20, 4, 4); | ||
| 745 | impl_channel!(GPIOTE20_CH5, GPIOTE20, 5, 5); | ||
| 746 | impl_channel!(GPIOTE20_CH6, GPIOTE20, 6, 6); | ||
| 747 | impl_channel!(GPIOTE20_CH7, GPIOTE20, 7, 7); | ||
| 748 | |||
| 749 | impl_channel!(GPIOTE30_CH0, GPIOTE30, 0, 8); | ||
| 750 | impl_channel!(GPIOTE30_CH1, GPIOTE30, 1, 9); | ||
| 751 | impl_channel!(GPIOTE30_CH2, GPIOTE30, 2, 10); | ||
| 752 | impl_channel!(GPIOTE30_CH3, GPIOTE30, 3, 11); | ||
| 753 | } else if #[cfg(feature = "_nrf51")] { | ||
| 754 | impl_channel!(GPIOTE_CH0, GPIOTE, 0, 0); | ||
| 755 | impl_channel!(GPIOTE_CH1, GPIOTE, 1, 1); | ||
| 756 | impl_channel!(GPIOTE_CH2, GPIOTE, 2, 2); | ||
| 757 | impl_channel!(GPIOTE_CH3, GPIOTE, 3, 3); | ||
| 758 | } else if #[cfg(all(feature = "_s", any(feature = "_nrf91", feature = "_nrf5340")))] { | ||
| 759 | impl_channel!(GPIOTE_CH0, GPIOTE0, 0, 0); | ||
| 760 | impl_channel!(GPIOTE_CH1, GPIOTE0, 1, 1); | ||
| 761 | impl_channel!(GPIOTE_CH2, GPIOTE0, 2, 2); | ||
| 762 | impl_channel!(GPIOTE_CH3, GPIOTE0, 3, 3); | ||
| 763 | impl_channel!(GPIOTE_CH4, GPIOTE0, 4, 4); | ||
| 764 | impl_channel!(GPIOTE_CH5, GPIOTE0, 5, 5); | ||
| 765 | impl_channel!(GPIOTE_CH6, GPIOTE0, 6, 6); | ||
| 766 | impl_channel!(GPIOTE_CH7, GPIOTE0, 7, 7); | ||
| 767 | } else if #[cfg(all(feature = "_ns", any(feature = "_nrf91", feature = "_nrf5340")))] { | ||
| 768 | impl_channel!(GPIOTE_CH0, GPIOTE1, 0, 0); | ||
| 769 | impl_channel!(GPIOTE_CH1, GPIOTE1, 1, 1); | ||
| 770 | impl_channel!(GPIOTE_CH2, GPIOTE1, 2, 2); | ||
| 771 | impl_channel!(GPIOTE_CH3, GPIOTE1, 3, 3); | ||
| 772 | impl_channel!(GPIOTE_CH4, GPIOTE1, 4, 4); | ||
| 773 | impl_channel!(GPIOTE_CH5, GPIOTE1, 5, 5); | ||
| 774 | impl_channel!(GPIOTE_CH6, GPIOTE1, 6, 6); | ||
| 775 | impl_channel!(GPIOTE_CH7, GPIOTE1, 7, 7); | ||
| 776 | } else { | ||
| 777 | impl_channel!(GPIOTE_CH0, GPIOTE, 0, 0); | ||
| 778 | impl_channel!(GPIOTE_CH1, GPIOTE, 1, 1); | ||
| 779 | impl_channel!(GPIOTE_CH2, GPIOTE, 2, 2); | ||
| 780 | impl_channel!(GPIOTE_CH3, GPIOTE, 3, 3); | ||
| 781 | impl_channel!(GPIOTE_CH4, GPIOTE, 4, 4); | ||
| 782 | impl_channel!(GPIOTE_CH5, GPIOTE, 5, 5); | ||
| 783 | impl_channel!(GPIOTE_CH6, GPIOTE, 6, 6); | ||
| 784 | impl_channel!(GPIOTE_CH7, GPIOTE, 7, 7); | ||
| 785 | } | ||
| 786 | } | ||
| 532 | 787 | ||
| 533 | // ==================== | 788 | // ==================== |
| 534 | 789 | ||
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 705c77453..2f7505746 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -76,14 +76,12 @@ pub(crate) mod util; | |||
| 76 | #[cfg(feature = "_time-driver")] | 76 | #[cfg(feature = "_time-driver")] |
| 77 | mod time_driver; | 77 | mod time_driver; |
| 78 | 78 | ||
| 79 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 80 | #[cfg(not(feature = "_nrf51"))] | 79 | #[cfg(not(feature = "_nrf51"))] |
| 81 | pub mod buffered_uarte; | 80 | pub mod buffered_uarte; |
| 82 | #[cfg(not(feature = "_nrf54l"))] // TODO | 81 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 83 | #[cfg(not(feature = "_nrf51"))] | 82 | #[cfg(not(feature = "_nrf51"))] |
| 84 | pub mod egu; | 83 | pub mod egu; |
| 85 | pub mod gpio; | 84 | pub mod gpio; |
| 86 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 87 | #[cfg(feature = "gpiote")] | 85 | #[cfg(feature = "gpiote")] |
| 88 | pub mod gpiote; | 86 | pub mod gpiote; |
| 89 | #[cfg(not(feature = "_nrf54l"))] // TODO | 87 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| @@ -119,9 +117,7 @@ pub mod pdm; | |||
| 119 | #[cfg(not(feature = "_nrf54l"))] // TODO | 117 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| 120 | #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))] | 118 | #[cfg(any(feature = "nrf52840", feature = "nrf9160-s", feature = "nrf9160-ns"))] |
| 121 | pub mod power; | 119 | pub mod power; |
| 122 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 123 | pub mod ppi; | 120 | pub mod ppi; |
| 124 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 125 | #[cfg(not(any( | 121 | #[cfg(not(any( |
| 126 | feature = "_nrf51", | 122 | feature = "_nrf51", |
| 127 | feature = "nrf52805", | 123 | feature = "nrf52805", |
| @@ -156,26 +152,19 @@ pub mod reset; | |||
| 156 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 152 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 157 | pub mod rng; | 153 | pub mod rng; |
| 158 | pub mod rtc; | 154 | pub mod rtc; |
| 159 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 160 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] | 155 | #[cfg(not(any(feature = "_nrf51", feature = "nrf52820", feature = "_nrf5340-net")))] |
| 161 | pub mod saadc; | 156 | pub mod saadc; |
| 162 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 163 | #[cfg(not(feature = "_nrf51"))] | 157 | #[cfg(not(feature = "_nrf51"))] |
| 164 | pub mod spim; | 158 | pub mod spim; |
| 165 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 166 | #[cfg(not(feature = "_nrf51"))] | 159 | #[cfg(not(feature = "_nrf51"))] |
| 167 | pub mod spis; | 160 | pub mod spis; |
| 168 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] | 161 | #[cfg(not(any(feature = "_nrf5340-app", feature = "_nrf91")))] |
| 169 | pub mod temp; | 162 | pub mod temp; |
| 170 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 171 | pub mod timer; | 163 | pub mod timer; |
| 172 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 173 | #[cfg(not(feature = "_nrf51"))] | 164 | #[cfg(not(feature = "_nrf51"))] |
| 174 | pub mod twim; | 165 | pub mod twim; |
| 175 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 176 | #[cfg(not(feature = "_nrf51"))] | 166 | #[cfg(not(feature = "_nrf51"))] |
| 177 | pub mod twis; | 167 | pub mod twis; |
| 178 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 179 | #[cfg(not(feature = "_nrf51"))] | 168 | #[cfg(not(feature = "_nrf51"))] |
| 180 | pub mod uarte; | 169 | pub mod uarte; |
| 181 | #[cfg(not(feature = "_nrf54l"))] // TODO | 170 | #[cfg(not(feature = "_nrf54l"))] // TODO |
| @@ -1153,7 +1142,6 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 1153 | } | 1142 | } |
| 1154 | 1143 | ||
| 1155 | // Init GPIOTE | 1144 | // Init GPIOTE |
| 1156 | #[cfg(not(feature = "_nrf54l"))] // TODO | ||
| 1157 | #[cfg(feature = "gpiote")] | 1145 | #[cfg(feature = "gpiote")] |
| 1158 | gpiote::init(config.gpiote_interrupt_priority); | 1146 | gpiote::init(config.gpiote_interrupt_priority); |
| 1159 | 1147 | ||
diff --git a/embassy-nrf/src/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 168647be3..d43a25c4e 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 2 | use crate::{Peri, pac}; | 2 | use crate::Peri; |
| 3 | 3 | ||
| 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; |
| 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; |
| 6 | 6 | ||
| 7 | pub(crate) fn regs() -> pac::dppic::Dppic { | 7 | #[cfg(not(feature = "_nrf54l"))] |
| 8 | pac::DPPIC | 8 | pub(crate) fn regs() -> crate::pac::dppic::Dppic { |
| 9 | crate::pac::DPPIC | ||
| 9 | } | 10 | } |
| 10 | 11 | ||
| 11 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { | 12 | impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> { |
| @@ -49,13 +50,13 @@ impl<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> Ppi<'d, | |||
| 49 | /// Enables the channel. | 50 | /// Enables the channel. |
| 50 | pub fn enable(&mut self) { | 51 | pub fn enable(&mut self) { |
| 51 | let n = self.ch.number(); | 52 | let n = self.ch.number(); |
| 52 | regs().chenset().write(|w| w.0 = 1 << n); | 53 | self.ch.regs().chenset().write(|w| w.0 = 1 << n); |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | /// Disables the channel. | 56 | /// Disables the channel. |
| 56 | pub fn disable(&mut self) { | 57 | pub fn disable(&mut self) { |
| 57 | let n = self.ch.number(); | 58 | let n = self.ch.number(); |
| 58 | regs().chenclr().write(|w| w.0 = 1 << n); | 59 | self.ch.regs().chenclr().write(|w| w.0 = 1 << n); |
| 59 | } | 60 | } |
| 60 | } | 61 | } |
| 61 | 62 | ||
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index f30c2218d..a880d3188 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs | |||
| @@ -21,11 +21,13 @@ use core::ptr::NonNull; | |||
| 21 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; | 21 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 22 | 22 | ||
| 23 | use crate::pac::common::{RW, Reg, W}; | 23 | use crate::pac::common::{RW, Reg, W}; |
| 24 | use crate::peripherals; | 24 | use crate::pac::{self}; |
| 25 | 25 | ||
| 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] | 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] |
| 27 | #[cfg_attr(feature = "_ppi", path = "ppi.rs")] | 27 | #[cfg_attr(feature = "_ppi", path = "ppi.rs")] |
| 28 | mod _version; | 28 | mod _version; |
| 29 | |||
| 30 | #[allow(unused_imports)] | ||
| 29 | pub(crate) use _version::*; | 31 | pub(crate) use _version::*; |
| 30 | 32 | ||
| 31 | /// PPI channel driver. | 33 | /// PPI channel driver. |
| @@ -47,7 +49,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 47 | /// | 49 | /// |
| 48 | /// The group is initialized as containing no channels. | 50 | /// The group is initialized as containing no channels. |
| 49 | pub fn new(g: Peri<'d, G>) -> Self { | 51 | pub fn new(g: Peri<'d, G>) -> Self { |
| 50 | let r = regs(); | 52 | let r = g.regs(); |
| 51 | let n = g.number(); | 53 | let n = g.number(); |
| 52 | r.chg(n).write(|_| ()); | 54 | r.chg(n).write(|_| ()); |
| 53 | 55 | ||
| @@ -61,7 +63,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 61 | &mut self, | 63 | &mut self, |
| 62 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, | 64 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, |
| 63 | ) { | 65 | ) { |
| 64 | let r = regs(); | 66 | let r = self.g.regs(); |
| 65 | let ng = self.g.number(); | 67 | let ng = self.g.number(); |
| 66 | let nc = ch.ch.number(); | 68 | let nc = ch.ch.number(); |
| 67 | r.chg(ng).modify(|w| w.set_ch(nc, true)); | 69 | r.chg(ng).modify(|w| w.set_ch(nc, true)); |
| @@ -74,7 +76,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 74 | &mut self, | 76 | &mut self, |
| 75 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, | 77 | ch: &Ppi<'_, C, EVENT_COUNT, TASK_COUNT>, |
| 76 | ) { | 78 | ) { |
| 77 | let r = regs(); | 79 | let r = self.g.regs(); |
| 78 | let ng = self.g.number(); | 80 | let ng = self.g.number(); |
| 79 | let nc = ch.ch.number(); | 81 | let nc = ch.ch.number(); |
| 80 | r.chg(ng).modify(|w| w.set_ch(nc, false)); | 82 | r.chg(ng).modify(|w| w.set_ch(nc, false)); |
| @@ -83,13 +85,13 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 83 | /// Enable all the channels in this group. | 85 | /// Enable all the channels in this group. |
| 84 | pub fn enable_all(&mut self) { | 86 | pub fn enable_all(&mut self) { |
| 85 | let n = self.g.number(); | 87 | let n = self.g.number(); |
| 86 | regs().tasks_chg(n).en().write_value(1); | 88 | self.g.regs().tasks_chg(n).en().write_value(1); |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | /// Disable all the channels in this group. | 91 | /// Disable all the channels in this group. |
| 90 | pub fn disable_all(&mut self) { | 92 | pub fn disable_all(&mut self) { |
| 91 | let n = self.g.number(); | 93 | let n = self.g.number(); |
| 92 | regs().tasks_chg(n).dis().write_value(1); | 94 | self.g.regs().tasks_chg(n).dis().write_value(1); |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | /// Get a reference to the "enable all" task. | 97 | /// Get a reference to the "enable all" task. |
| @@ -97,7 +99,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 97 | /// When triggered, it will enable all the channels in this group. | 99 | /// When triggered, it will enable all the channels in this group. |
| 98 | pub fn task_enable_all(&self) -> Task<'d> { | 100 | pub fn task_enable_all(&self) -> Task<'d> { |
| 99 | let n = self.g.number(); | 101 | let n = self.g.number(); |
| 100 | Task::from_reg(regs().tasks_chg(n).en()) | 102 | Task::from_reg(self.g.regs().tasks_chg(n).en()) |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | /// Get a reference to the "disable all" task. | 105 | /// Get a reference to the "disable all" task. |
| @@ -105,7 +107,7 @@ impl<'d, G: Group> PpiGroup<'d, G> { | |||
| 105 | /// When triggered, it will disable all the channels in this group. | 107 | /// When triggered, it will disable all the channels in this group. |
| 106 | pub fn task_disable_all(&self) -> Task<'d> { | 108 | pub fn task_disable_all(&self) -> Task<'d> { |
| 107 | let n = self.g.number(); | 109 | let n = self.g.number(); |
| 108 | Task::from_reg(regs().tasks_chg(n).dis()) | 110 | Task::from_reg(self.g.regs().tasks_chg(n).dis()) |
| 109 | } | 111 | } |
| 110 | } | 112 | } |
| 111 | impl<G: Group> PpiGroup<'static, G> { | 113 | impl<G: Group> PpiGroup<'static, G> { |
| @@ -119,7 +121,7 @@ impl<G: Group> PpiGroup<'static, G> { | |||
| 119 | 121 | ||
| 120 | impl<'d, G: Group> Drop for PpiGroup<'d, G> { | 122 | impl<'d, G: Group> Drop for PpiGroup<'d, G> { |
| 121 | fn drop(&mut self) { | 123 | fn drop(&mut self) { |
| 122 | let r = regs(); | 124 | let r = self.g.regs(); |
| 123 | let n = self.g.number(); | 125 | let n = self.g.number(); |
| 124 | r.chg(n).write(|_| ()); | 126 | r.chg(n).write(|_| ()); |
| 125 | } | 127 | } |
| @@ -211,8 +213,16 @@ unsafe impl Send for Event<'_> {} | |||
| 211 | // ====================== | 213 | // ====================== |
| 212 | // traits | 214 | // traits |
| 213 | 215 | ||
| 214 | pub(crate) trait SealedChannel {} | 216 | pub(crate) trait SealedChannel { |
| 215 | pub(crate) trait SealedGroup {} | 217 | #[cfg(feature = "_dppi")] |
| 218 | fn regs(&self) -> pac::dppic::Dppic; | ||
| 219 | } | ||
| 220 | pub(crate) trait SealedGroup { | ||
| 221 | #[cfg(feature = "_dppi")] | ||
| 222 | fn regs(&self) -> pac::dppic::Dppic; | ||
| 223 | #[cfg(not(feature = "_dppi"))] | ||
| 224 | fn regs(&self) -> pac::ppi::Ppi; | ||
| 225 | } | ||
| 216 | 226 | ||
| 217 | /// Interface for PPI channels. | 227 | /// Interface for PPI channels. |
| 218 | #[allow(private_bounds)] | 228 | #[allow(private_bounds)] |
| @@ -241,9 +251,16 @@ pub trait Group: SealedGroup + PeripheralType + Into<AnyGroup> + Sized + 'static | |||
| 241 | /// This can be used to have fewer generic parameters in some places. | 251 | /// This can be used to have fewer generic parameters in some places. |
| 242 | pub struct AnyStaticChannel { | 252 | pub struct AnyStaticChannel { |
| 243 | pub(crate) number: u8, | 253 | pub(crate) number: u8, |
| 254 | #[cfg(feature = "_dppi")] | ||
| 255 | pub(crate) regs: pac::dppic::Dppic, | ||
| 244 | } | 256 | } |
| 245 | impl_peripheral!(AnyStaticChannel); | 257 | impl_peripheral!(AnyStaticChannel); |
| 246 | impl SealedChannel for AnyStaticChannel {} | 258 | impl SealedChannel for AnyStaticChannel { |
| 259 | #[cfg(feature = "_dppi")] | ||
| 260 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 261 | self.regs | ||
| 262 | } | ||
| 263 | } | ||
| 247 | impl Channel for AnyStaticChannel { | 264 | impl Channel for AnyStaticChannel { |
| 248 | fn number(&self) -> usize { | 265 | fn number(&self) -> usize { |
| 249 | self.number as usize | 266 | self.number as usize |
| @@ -255,9 +272,16 @@ impl StaticChannel for AnyStaticChannel {} | |||
| 255 | /// This can be used to have fewer generic parameters in some places. | 272 | /// This can be used to have fewer generic parameters in some places. |
| 256 | pub struct AnyConfigurableChannel { | 273 | pub struct AnyConfigurableChannel { |
| 257 | pub(crate) number: u8, | 274 | pub(crate) number: u8, |
| 275 | #[cfg(feature = "_dppi")] | ||
| 276 | pub(crate) regs: pac::dppic::Dppic, | ||
| 258 | } | 277 | } |
| 259 | impl_peripheral!(AnyConfigurableChannel); | 278 | impl_peripheral!(AnyConfigurableChannel); |
| 260 | impl SealedChannel for AnyConfigurableChannel {} | 279 | impl SealedChannel for AnyConfigurableChannel { |
| 280 | #[cfg(feature = "_dppi")] | ||
| 281 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 282 | self.regs | ||
| 283 | } | ||
| 284 | } | ||
| 261 | impl Channel for AnyConfigurableChannel { | 285 | impl Channel for AnyConfigurableChannel { |
| 262 | fn number(&self) -> usize { | 286 | fn number(&self) -> usize { |
| 263 | self.number as usize | 287 | self.number as usize |
| @@ -267,32 +291,41 @@ impl ConfigurableChannel for AnyConfigurableChannel {} | |||
| 267 | 291 | ||
| 268 | #[cfg(not(feature = "_nrf51"))] | 292 | #[cfg(not(feature = "_nrf51"))] |
| 269 | macro_rules! impl_ppi_channel { | 293 | macro_rules! impl_ppi_channel { |
| 270 | ($type:ident, $number:expr) => { | 294 | ($type:ident, $inst:ident, $number:expr) => { |
| 271 | impl crate::ppi::SealedChannel for peripherals::$type {} | 295 | impl crate::ppi::SealedChannel for peripherals::$type { |
| 296 | #[cfg(feature = "_dppi")] | ||
| 297 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 298 | pac::$inst | ||
| 299 | } | ||
| 300 | } | ||
| 272 | impl crate::ppi::Channel for peripherals::$type { | 301 | impl crate::ppi::Channel for peripherals::$type { |
| 273 | fn number(&self) -> usize { | 302 | fn number(&self) -> usize { |
| 274 | $number | 303 | $number |
| 275 | } | 304 | } |
| 276 | } | 305 | } |
| 277 | }; | 306 | }; |
| 278 | ($type:ident, $number:expr => static) => { | 307 | ($type:ident, $inst:ident, $number:expr => static) => { |
| 279 | impl_ppi_channel!($type, $number); | 308 | impl_ppi_channel!($type, $inst, $number); |
| 280 | impl crate::ppi::StaticChannel for peripherals::$type {} | 309 | impl crate::ppi::StaticChannel for peripherals::$type {} |
| 281 | impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { | 310 | impl From<peripherals::$type> for crate::ppi::AnyStaticChannel { |
| 282 | fn from(val: peripherals::$type) -> Self { | 311 | fn from(val: peripherals::$type) -> Self { |
| 283 | Self { | 312 | Self { |
| 284 | number: crate::ppi::Channel::number(&val) as u8, | 313 | number: crate::ppi::Channel::number(&val) as u8, |
| 314 | #[cfg(feature = "_dppi")] | ||
| 315 | regs: pac::$inst, | ||
| 285 | } | 316 | } |
| 286 | } | 317 | } |
| 287 | } | 318 | } |
| 288 | }; | 319 | }; |
| 289 | ($type:ident, $number:expr => configurable) => { | 320 | ($type:ident, $inst:ident, $number:expr => configurable) => { |
| 290 | impl_ppi_channel!($type, $number); | 321 | impl_ppi_channel!($type, $inst, $number); |
| 291 | impl crate::ppi::ConfigurableChannel for peripherals::$type {} | 322 | impl crate::ppi::ConfigurableChannel for peripherals::$type {} |
| 292 | impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { | 323 | impl From<peripherals::$type> for crate::ppi::AnyConfigurableChannel { |
| 293 | fn from(val: peripherals::$type) -> Self { | 324 | fn from(val: peripherals::$type) -> Self { |
| 294 | Self { | 325 | Self { |
| 295 | number: crate::ppi::Channel::number(&val) as u8, | 326 | number: crate::ppi::Channel::number(&val) as u8, |
| 327 | #[cfg(feature = "_dppi")] | ||
| 328 | regs: pac::$inst, | ||
| 296 | } | 329 | } |
| 297 | } | 330 | } |
| 298 | } | 331 | } |
| @@ -304,40 +337,54 @@ macro_rules! impl_ppi_channel { | |||
| 304 | 337 | ||
| 305 | /// A type erased PPI group. | 338 | /// A type erased PPI group. |
| 306 | pub struct AnyGroup { | 339 | pub struct AnyGroup { |
| 307 | number: u8, | 340 | pub(crate) number: u8, |
| 341 | #[cfg(feature = "_dppi")] | ||
| 342 | pub(crate) regs: pac::dppic::Dppic, | ||
| 343 | #[cfg(not(feature = "_dppi"))] | ||
| 344 | pub(crate) regs: pac::ppi::Ppi, | ||
| 308 | } | 345 | } |
| 309 | impl_peripheral!(AnyGroup); | 346 | impl_peripheral!(AnyGroup); |
| 310 | impl SealedGroup for AnyGroup {} | 347 | impl SealedGroup for AnyGroup { |
| 348 | #[cfg(feature = "_dppi")] | ||
| 349 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 350 | self.regs | ||
| 351 | } | ||
| 352 | #[cfg(not(feature = "_dppi"))] | ||
| 353 | fn regs(&self) -> pac::ppi::Ppi { | ||
| 354 | self.regs | ||
| 355 | } | ||
| 356 | } | ||
| 311 | impl Group for AnyGroup { | 357 | impl Group for AnyGroup { |
| 312 | fn number(&self) -> usize { | 358 | fn number(&self) -> usize { |
| 313 | self.number as usize | 359 | self.number as usize |
| 314 | } | 360 | } |
| 315 | } | 361 | } |
| 316 | 362 | ||
| 317 | macro_rules! impl_group { | 363 | macro_rules! impl_ppi_group { |
| 318 | ($type:ident, $number:expr) => { | 364 | ($type:ident, $inst:ident, $number:expr) => { |
| 319 | impl SealedGroup for peripherals::$type {} | 365 | impl crate::ppi::SealedGroup for crate::peripherals::$type { |
| 320 | impl Group for peripherals::$type { | 366 | #[cfg(feature = "_dppi")] |
| 367 | fn regs(&self) -> pac::dppic::Dppic { | ||
| 368 | pac::$inst | ||
| 369 | } | ||
| 370 | #[cfg(not(feature = "_dppi"))] | ||
| 371 | fn regs(&self) -> pac::ppi::Ppi { | ||
| 372 | pac::$inst | ||
| 373 | } | ||
| 374 | } | ||
| 375 | impl crate::ppi::Group for crate::peripherals::$type { | ||
| 321 | fn number(&self) -> usize { | 376 | fn number(&self) -> usize { |
| 322 | $number | 377 | $number |
| 323 | } | 378 | } |
| 324 | } | 379 | } |
| 325 | 380 | ||
| 326 | impl From<peripherals::$type> for crate::ppi::AnyGroup { | 381 | impl From<crate::peripherals::$type> for crate::ppi::AnyGroup { |
| 327 | fn from(val: peripherals::$type) -> Self { | 382 | fn from(val: crate::peripherals::$type) -> Self { |
| 328 | Self { | 383 | Self { |
| 329 | number: crate::ppi::Group::number(&val) as u8, | 384 | number: crate::ppi::Group::number(&val) as u8, |
| 385 | regs: pac::$inst, | ||
| 330 | } | 386 | } |
| 331 | } | 387 | } |
| 332 | } | 388 | } |
| 333 | }; | 389 | }; |
| 334 | } | 390 | } |
| 335 | |||
| 336 | impl_group!(PPI_GROUP0, 0); | ||
| 337 | impl_group!(PPI_GROUP1, 1); | ||
| 338 | impl_group!(PPI_GROUP2, 2); | ||
| 339 | impl_group!(PPI_GROUP3, 3); | ||
| 340 | #[cfg(not(feature = "_nrf51"))] | ||
| 341 | impl_group!(PPI_GROUP4, 4); | ||
| 342 | #[cfg(not(feature = "_nrf51"))] | ||
| 343 | impl_group!(PPI_GROUP5, 5); | ||
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index 00b3278c7..04eb14a77 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -203,7 +203,7 @@ impl<'d> SequencePwm<'d> { | |||
| 203 | /// Interacting with the sequence while it runs puts it in an unknown state | 203 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 204 | #[inline(always)] | 204 | #[inline(always)] |
| 205 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { | 205 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { |
| 206 | Task::from_reg(self.r.tasks_seqstart(0)) | 206 | Task::from_reg(self.r.tasks_dma().seq(0).start()) |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | /// Returns reference to `Seq1 Started` task endpoint for PPI. | 209 | /// Returns reference to `Seq1 Started` task endpoint for PPI. |
| @@ -212,7 +212,7 @@ impl<'d> SequencePwm<'d> { | |||
| 212 | /// Interacting with the sequence while it runs puts it in an unknown state | 212 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 213 | #[inline(always)] | 213 | #[inline(always)] |
| 214 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { | 214 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { |
| 215 | Task::from_reg(self.r.tasks_seqstart(1)) | 215 | Task::from_reg(self.r.tasks_dma().seq(1).start()) |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | /// Returns reference to `NextStep` task endpoint for PPI. | 218 | /// Returns reference to `NextStep` task endpoint for PPI. |
| @@ -444,6 +444,21 @@ pub struct Sequencer<'d, 's> { | |||
| 444 | sequence1: Option<Sequence<'s>>, | 444 | sequence1: Option<Sequence<'s>>, |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | #[cfg(feature = "_nrf54l")] | ||
| 448 | fn pwmseq(r: pac::pwm::Pwm, n: usize) -> pac::pwm::PwmSeq { | ||
| 449 | r.seq(n) | ||
| 450 | } | ||
| 451 | |||
| 452 | #[cfg(not(feature = "_nrf54l"))] | ||
| 453 | fn pwmseq(r: pac::pwm::Pwm, n: usize) -> pac::pwm::DmaSeq { | ||
| 454 | r.dma().seq(n) | ||
| 455 | } | ||
| 456 | |||
| 457 | #[cfg(feature = "_nrf54l")] | ||
| 458 | const CNT_UNIT: u32 = 2; | ||
| 459 | #[cfg(not(feature = "_nrf54l"))] | ||
| 460 | const CNT_UNIT: u32 = 1; | ||
| 461 | |||
| 447 | impl<'d, 's> Sequencer<'d, 's> { | 462 | impl<'d, 's> Sequencer<'d, 's> { |
| 448 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 | 463 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 |
| 449 | /// will be used twice in the one loop. | 464 | /// will be used twice in the one loop. |
| @@ -476,15 +491,21 @@ impl<'d, 's> Sequencer<'d, 's> { | |||
| 476 | 491 | ||
| 477 | let r = self._pwm.r; | 492 | let r = self._pwm.r; |
| 478 | 493 | ||
| 479 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); | 494 | pwmseq(r, 0).refresh().write(|w| w.0 = sequence0.config.refresh); |
| 480 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); | 495 | pwmseq(r, 0).enddelay().write(|w| w.0 = sequence0.config.end_delay); |
| 481 | r.seq(0).ptr().write_value(sequence0.words.as_ptr() as u32); | 496 | r.dma().seq(0).ptr().write_value(sequence0.words.as_ptr() as u32); |
| 482 | r.seq(0).cnt().write(|w| w.0 = sequence0.words.len() as u32); | 497 | r.dma() |
| 483 | 498 | .seq(0) | |
| 484 | r.seq(1).refresh().write(|w| w.0 = alt_sequence.config.refresh); | 499 | .maxcnt() |
| 485 | r.seq(1).enddelay().write(|w| w.0 = alt_sequence.config.end_delay); | 500 | .write(|w| w.0 = sequence0.words.len() as u32 * CNT_UNIT); |
| 486 | r.seq(1).ptr().write_value(alt_sequence.words.as_ptr() as u32); | 501 | |
| 487 | r.seq(1).cnt().write(|w| w.0 = alt_sequence.words.len() as u32); | 502 | pwmseq(r, 1).refresh().write(|w| w.0 = alt_sequence.config.refresh); |
| 503 | pwmseq(r, 1).enddelay().write(|w| w.0 = alt_sequence.config.end_delay); | ||
| 504 | r.dma().seq(1).ptr().write_value(alt_sequence.words.as_ptr() as u32); | ||
| 505 | r.dma() | ||
| 506 | .seq(1) | ||
| 507 | .maxcnt() | ||
| 508 | .write(|w| w.0 = alt_sequence.words.len() as u32 * CNT_UNIT); | ||
| 488 | 509 | ||
| 489 | r.enable().write(|w| w.set_enable(true)); | 510 | r.enable().write(|w| w.set_enable(true)); |
| 490 | 511 | ||
| @@ -500,11 +521,11 @@ impl<'d, 's> Sequencer<'d, 's> { | |||
| 500 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again | 521 | // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again |
| 501 | SequenceMode::Infinite => { | 522 | SequenceMode::Infinite => { |
| 502 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::from_bits(1))); | 523 | r.loop_().write(|w| w.set_cnt(vals::LoopCnt::from_bits(1))); |
| 503 | r.shorts().write(|w| w.set_loopsdone_seqstart0(true)); | 524 | r.shorts().write(|w| w.set_loopsdone_dma_seq0_start(true)); |
| 504 | } | 525 | } |
| 505 | } | 526 | } |
| 506 | 527 | ||
| 507 | r.tasks_seqstart(seqstart_index).write_value(1); | 528 | r.tasks_dma().seq(seqstart_index).start().write_value(1); |
| 508 | 529 | ||
| 509 | Ok(()) | 530 | Ok(()) |
| 510 | } | 531 | } |
| @@ -781,10 +802,10 @@ impl<'d> SimplePwm<'d> { | |||
| 781 | // Enable | 802 | // Enable |
| 782 | r.enable().write(|w| w.set_enable(true)); | 803 | r.enable().write(|w| w.set_enable(true)); |
| 783 | 804 | ||
| 784 | r.seq(0).ptr().write_value((pwm.duty).as_ptr() as u32); | 805 | r.dma().seq(0).ptr().write_value((pwm.duty).as_ptr() as u32); |
| 785 | r.seq(0).cnt().write(|w| w.0 = 4); | 806 | r.dma().seq(0).maxcnt().write(|w| w.0 = 4 * CNT_UNIT); |
| 786 | r.seq(0).refresh().write(|w| w.0 = 0); | 807 | pwmseq(r, 0).refresh().write(|w| w.0 = 0); |
| 787 | r.seq(0).enddelay().write(|w| w.0 = 0); | 808 | pwmseq(r, 0).enddelay().write(|w| w.0 = 0); |
| 788 | 809 | ||
| 789 | r.decoder().write(|w| { | 810 | r.decoder().write(|w| { |
| 790 | w.set_load(vals::Load::INDIVIDUAL); | 811 | w.set_load(vals::Load::INDIVIDUAL); |
| @@ -846,7 +867,7 @@ impl<'d> SimplePwm<'d> { | |||
| 846 | /// Transfer the duty cycles from `self` to the peripheral. | 867 | /// Transfer the duty cycles from `self` to the peripheral. |
| 847 | fn sync_duty_cyles_to_peripheral(&self) { | 868 | fn sync_duty_cyles_to_peripheral(&self) { |
| 848 | // reload ptr in case self was moved | 869 | // reload ptr in case self was moved |
| 849 | self.r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); | 870 | self.r.dma().seq(0).ptr().write_value((self.duty).as_ptr() as u32); |
| 850 | 871 | ||
| 851 | // defensive before seqstart | 872 | // defensive before seqstart |
| 852 | compiler_fence(Ordering::SeqCst); | 873 | compiler_fence(Ordering::SeqCst); |
| @@ -854,7 +875,7 @@ impl<'d> SimplePwm<'d> { | |||
| 854 | self.r.events_seqend(0).write_value(0); | 875 | self.r.events_seqend(0).write_value(0); |
| 855 | 876 | ||
| 856 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 877 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 857 | self.r.tasks_seqstart(0).write_value(1); | 878 | self.r.tasks_dma().seq(0).start().write_value(1); |
| 858 | 879 | ||
| 859 | // defensive wait until waveform is loaded after seqstart so set_duty | 880 | // defensive wait until waveform is loaded after seqstart so set_duty |
| 860 | // can't be called again while dma is still reading | 881 | // can't be called again while dma is still reading |
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index a199c1c4d..ca8cbd73e 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -10,6 +10,7 @@ use core::task::Poll; | |||
| 10 | use embassy_hal_internal::drop::OnDrop; | 10 | use embassy_hal_internal::drop::OnDrop; |
| 11 | use embassy_hal_internal::{Peri, impl_peripheral}; | 11 | use embassy_hal_internal::{Peri, impl_peripheral}; |
| 12 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 13 | #[cfg(not(feature = "_nrf54l"))] | ||
| 13 | pub(crate) use vals::Psel as InputChannel; | 14 | pub(crate) use vals::Psel as InputChannel; |
| 14 | 15 | ||
| 15 | use crate::interrupt::InterruptExt; | 16 | use crate::interrupt::InterruptExt; |
| @@ -84,6 +85,7 @@ pub struct ChannelConfig<'d> { | |||
| 84 | /// Gain used to control the effective input range of the SAADC. | 85 | /// Gain used to control the effective input range of the SAADC. |
| 85 | pub gain: Gain, | 86 | pub gain: Gain, |
| 86 | /// Positive channel resistor control. | 87 | /// Positive channel resistor control. |
| 88 | #[cfg(not(feature = "_nrf54l"))] | ||
| 87 | pub resistor: Resistor, | 89 | pub resistor: Resistor, |
| 88 | /// Acquisition time in microseconds. | 90 | /// Acquisition time in microseconds. |
| 89 | pub time: Time, | 91 | pub time: Time, |
| @@ -98,7 +100,11 @@ impl<'d> ChannelConfig<'d> { | |||
| 98 | pub fn single_ended(input: impl Input + 'd) -> Self { | 100 | pub fn single_ended(input: impl Input + 'd) -> Self { |
| 99 | Self { | 101 | Self { |
| 100 | reference: Reference::INTERNAL, | 102 | reference: Reference::INTERNAL, |
| 103 | #[cfg(not(feature = "_nrf54l"))] | ||
| 101 | gain: Gain::GAIN1_6, | 104 | gain: Gain::GAIN1_6, |
| 105 | #[cfg(feature = "_nrf54l")] | ||
| 106 | gain: Gain::GAIN2_8, | ||
| 107 | #[cfg(not(feature = "_nrf54l"))] | ||
| 102 | resistor: Resistor::BYPASS, | 108 | resistor: Resistor::BYPASS, |
| 103 | time: Time::_10US, | 109 | time: Time::_10US, |
| 104 | p_channel: input.degrade_saadc(), | 110 | p_channel: input.degrade_saadc(), |
| @@ -109,7 +115,11 @@ impl<'d> ChannelConfig<'d> { | |||
| 109 | pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { | 115 | pub fn differential(p_input: impl Input + 'd, n_input: impl Input + 'd) -> Self { |
| 110 | Self { | 116 | Self { |
| 111 | reference: Reference::INTERNAL, | 117 | reference: Reference::INTERNAL, |
| 118 | #[cfg(not(feature = "_nrf54l"))] | ||
| 112 | gain: Gain::GAIN1_6, | 119 | gain: Gain::GAIN1_6, |
| 120 | #[cfg(feature = "_nrf54l")] | ||
| 121 | gain: Gain::GAIN2_8, | ||
| 122 | #[cfg(not(feature = "_nrf54l"))] | ||
| 113 | resistor: Resistor::BYPASS, | 123 | resistor: Resistor::BYPASS, |
| 114 | time: Time::_10US, | 124 | time: Time::_10US, |
| 115 | p_channel: p_input.degrade_saadc(), | 125 | p_channel: p_input.degrade_saadc(), |
| @@ -118,6 +128,8 @@ impl<'d> ChannelConfig<'d> { | |||
| 118 | } | 128 | } |
| 119 | } | 129 | } |
| 120 | 130 | ||
| 131 | const CNT_UNIT: usize = if cfg!(feature = "_nrf54l") { 2 } else { 1 }; | ||
| 132 | |||
| 121 | /// Value returned by the SAADC callback, deciding what happens next. | 133 | /// Value returned by the SAADC callback, deciding what happens next. |
| 122 | #[derive(PartialEq)] | 134 | #[derive(PartialEq)] |
| 123 | pub enum CallbackResult { | 135 | pub enum CallbackResult { |
| @@ -150,19 +162,38 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 150 | r.oversample().write(|w| w.set_oversample(oversample.into())); | 162 | r.oversample().write(|w| w.set_oversample(oversample.into())); |
| 151 | 163 | ||
| 152 | for (i, cc) in channel_configs.iter().enumerate() { | 164 | for (i, cc) in channel_configs.iter().enumerate() { |
| 165 | #[cfg(not(feature = "_nrf54l"))] | ||
| 153 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); | 166 | r.ch(i).pselp().write(|w| w.set_pselp(cc.p_channel.channel())); |
| 167 | #[cfg(feature = "_nrf54l")] | ||
| 168 | r.ch(i).pselp().write(|w| { | ||
| 169 | w.set_port(cc.p_channel.port()); | ||
| 170 | w.set_pin(cc.p_channel.pin()); | ||
| 171 | w.set_internal(cc.p_channel.internal()); | ||
| 172 | w.set_connect(cc.p_channel.connect()); | ||
| 173 | }); | ||
| 154 | if let Some(n_channel) = &cc.n_channel { | 174 | if let Some(n_channel) = &cc.n_channel { |
| 175 | #[cfg(not(feature = "_nrf54l"))] | ||
| 155 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); | 176 | r.ch(i).pseln().write(|w| w.set_pseln(n_channel.channel())); |
| 177 | #[cfg(feature = "_nrf54l")] | ||
| 178 | r.ch(i).pseln().write(|w| { | ||
| 179 | w.set_port(n_channel.port()); | ||
| 180 | w.set_pin(n_channel.pin()); | ||
| 181 | w.set_connect(n_channel.connect().to_bits().into()); | ||
| 182 | }); | ||
| 156 | } | 183 | } |
| 157 | r.ch(i).config().write(|w| { | 184 | r.ch(i).config().write(|w| { |
| 158 | w.set_refsel(cc.reference.into()); | 185 | w.set_refsel(cc.reference.into()); |
| 159 | w.set_gain(cc.gain.into()); | 186 | w.set_gain(cc.gain.into()); |
| 160 | w.set_tacq(cc.time.into()); | 187 | w.set_tacq(cc.time.into()); |
| 188 | #[cfg(feature = "_nrf54l")] | ||
| 189 | w.set_tconv(7); // 7 is the default from the Nordic C driver | ||
| 161 | w.set_mode(match cc.n_channel { | 190 | w.set_mode(match cc.n_channel { |
| 162 | None => vals::ConfigMode::SE, | 191 | None => vals::ConfigMode::SE, |
| 163 | Some(_) => vals::ConfigMode::DIFF, | 192 | Some(_) => vals::ConfigMode::DIFF, |
| 164 | }); | 193 | }); |
| 194 | #[cfg(not(feature = "_nrf54l"))] | ||
| 165 | w.set_resp(cc.resistor.into()); | 195 | w.set_resp(cc.resistor.into()); |
| 196 | #[cfg(not(feature = "_nrf54l"))] | ||
| 166 | w.set_resn(vals::Resn::BYPASS); | 197 | w.set_resn(vals::Resn::BYPASS); |
| 167 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); | 198 | w.set_burst(!matches!(oversample, Oversample::BYPASS)); |
| 168 | }); | 199 | }); |
| @@ -222,7 +253,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 222 | 253 | ||
| 223 | // Set up the DMA | 254 | // Set up the DMA |
| 224 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); | 255 | r.result().ptr().write_value(buf.as_mut_ptr() as u32); |
| 225 | r.result().maxcnt().write(|w| w.set_maxcnt(N as _)); | 256 | r.result().maxcnt().write(|w| w.set_maxcnt((N * CNT_UNIT) as _)); |
| 226 | 257 | ||
| 227 | // Reset and enable the end event | 258 | // Reset and enable the end event |
| 228 | r.events_end().write_value(0); | 259 | r.events_end().write_value(0); |
| @@ -354,7 +385,7 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 354 | 385 | ||
| 355 | // Set up the initial DMA | 386 | // Set up the initial DMA |
| 356 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); | 387 | r.result().ptr().write_value(bufs[0].as_mut_ptr() as u32); |
| 357 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N) as _)); | 388 | r.result().maxcnt().write(|w| w.set_maxcnt((N0 * N * CNT_UNIT) as _)); |
| 358 | 389 | ||
| 359 | // Reset and enable the events | 390 | // Reset and enable the events |
| 360 | r.events_end().write_value(0); | 391 | r.events_end().write_value(0); |
| @@ -473,12 +504,21 @@ impl<'d, const N: usize> Drop for Saadc<'d, N> { | |||
| 473 | let r = Self::regs(); | 504 | let r = Self::regs(); |
| 474 | r.enable().write(|w| w.set_enable(false)); | 505 | r.enable().write(|w| w.set_enable(false)); |
| 475 | for i in 0..N { | 506 | for i in 0..N { |
| 476 | r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); | 507 | #[cfg(not(feature = "_nrf54l"))] |
| 477 | r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); | 508 | { |
| 509 | r.ch(i).pselp().write(|w| w.set_pselp(InputChannel::NC)); | ||
| 510 | r.ch(i).pseln().write(|w| w.set_pseln(InputChannel::NC)); | ||
| 511 | } | ||
| 512 | #[cfg(feature = "_nrf54l")] | ||
| 513 | { | ||
| 514 | r.ch(i).pselp().write(|w| w.set_connect(vals::PselpConnect::NC)); | ||
| 515 | r.ch(i).pseln().write(|w| w.set_connect(vals::PselnConnect::NC)); | ||
| 516 | } | ||
| 478 | } | 517 | } |
| 479 | } | 518 | } |
| 480 | } | 519 | } |
| 481 | 520 | ||
| 521 | #[cfg(not(feature = "_nrf54l"))] | ||
| 482 | impl From<Gain> for vals::Gain { | 522 | impl From<Gain> for vals::Gain { |
| 483 | fn from(gain: Gain) -> Self { | 523 | fn from(gain: Gain) -> Self { |
| 484 | match gain { | 524 | match gain { |
| @@ -494,7 +534,24 @@ impl From<Gain> for vals::Gain { | |||
| 494 | } | 534 | } |
| 495 | } | 535 | } |
| 496 | 536 | ||
| 537 | #[cfg(feature = "_nrf54l")] | ||
| 538 | impl From<Gain> for vals::Gain { | ||
| 539 | fn from(gain: Gain) -> Self { | ||
| 540 | match gain { | ||
| 541 | Gain::GAIN2_8 => vals::Gain::GAIN2_8, | ||
| 542 | Gain::GAIN2_7 => vals::Gain::GAIN2_7, | ||
| 543 | Gain::GAIN2_6 => vals::Gain::GAIN2_6, | ||
| 544 | Gain::GAIN2_5 => vals::Gain::GAIN2_5, | ||
| 545 | Gain::GAIN2_4 => vals::Gain::GAIN2_4, | ||
| 546 | Gain::GAIN2_3 => vals::Gain::GAIN2_3, | ||
| 547 | Gain::GAIN1 => vals::Gain::GAIN1, | ||
| 548 | Gain::GAIN2 => vals::Gain::GAIN2, | ||
| 549 | } | ||
| 550 | } | ||
| 551 | } | ||
| 552 | |||
| 497 | /// Gain control | 553 | /// Gain control |
| 554 | #[cfg(not(feature = "_nrf54l"))] | ||
| 498 | #[non_exhaustive] | 555 | #[non_exhaustive] |
| 499 | #[derive(Clone, Copy)] | 556 | #[derive(Clone, Copy)] |
| 500 | pub enum Gain { | 557 | pub enum Gain { |
| @@ -516,11 +573,37 @@ pub enum Gain { | |||
| 516 | GAIN4 = 7, | 573 | GAIN4 = 7, |
| 517 | } | 574 | } |
| 518 | 575 | ||
| 576 | /// Gain control | ||
| 577 | #[cfg(feature = "_nrf54l")] | ||
| 578 | #[non_exhaustive] | ||
| 579 | #[derive(Clone, Copy)] | ||
| 580 | pub enum Gain { | ||
| 581 | /// 2/8 | ||
| 582 | GAIN2_8 = 0, | ||
| 583 | /// 2/7 | ||
| 584 | GAIN2_7 = 1, | ||
| 585 | /// 2/6 | ||
| 586 | GAIN2_6 = 2, | ||
| 587 | /// 2/5 | ||
| 588 | GAIN2_5 = 3, | ||
| 589 | /// 2/4 | ||
| 590 | GAIN2_4 = 4, | ||
| 591 | /// 2/3 | ||
| 592 | GAIN2_3 = 5, | ||
| 593 | /// 1 | ||
| 594 | GAIN1 = 6, | ||
| 595 | /// 2 | ||
| 596 | GAIN2 = 7, | ||
| 597 | } | ||
| 598 | |||
| 519 | impl From<Reference> for vals::Refsel { | 599 | impl From<Reference> for vals::Refsel { |
| 520 | fn from(reference: Reference) -> Self { | 600 | fn from(reference: Reference) -> Self { |
| 521 | match reference { | 601 | match reference { |
| 522 | Reference::INTERNAL => vals::Refsel::INTERNAL, | 602 | Reference::INTERNAL => vals::Refsel::INTERNAL, |
| 603 | #[cfg(not(feature = "_nrf54l"))] | ||
| 523 | Reference::VDD1_4 => vals::Refsel::VDD1_4, | 604 | Reference::VDD1_4 => vals::Refsel::VDD1_4, |
| 605 | #[cfg(feature = "_nrf54l")] | ||
| 606 | Reference::EXTERNAL => vals::Refsel::EXTERNAL, | ||
| 524 | } | 607 | } |
| 525 | } | 608 | } |
| 526 | } | 609 | } |
| @@ -531,10 +614,15 @@ impl From<Reference> for vals::Refsel { | |||
| 531 | pub enum Reference { | 614 | pub enum Reference { |
| 532 | /// Internal reference (0.6 V) | 615 | /// Internal reference (0.6 V) |
| 533 | INTERNAL = 0, | 616 | INTERNAL = 0, |
| 617 | #[cfg(not(feature = "_nrf54l"))] | ||
| 534 | /// VDD/4 as reference | 618 | /// VDD/4 as reference |
| 535 | VDD1_4 = 1, | 619 | VDD1_4 = 1, |
| 620 | /// PADC_EXT_REF_1V2 as reference | ||
| 621 | #[cfg(feature = "_nrf54l")] | ||
| 622 | EXTERNAL = 1, | ||
| 536 | } | 623 | } |
| 537 | 624 | ||
| 625 | #[cfg(not(feature = "_nrf54l"))] | ||
| 538 | impl From<Resistor> for vals::Resp { | 626 | impl From<Resistor> for vals::Resp { |
| 539 | fn from(resistor: Resistor) -> Self { | 627 | fn from(resistor: Resistor) -> Self { |
| 540 | match resistor { | 628 | match resistor { |
| @@ -549,6 +637,7 @@ impl From<Resistor> for vals::Resp { | |||
| 549 | /// Positive channel resistor control | 637 | /// Positive channel resistor control |
| 550 | #[non_exhaustive] | 638 | #[non_exhaustive] |
| 551 | #[derive(Clone, Copy)] | 639 | #[derive(Clone, Copy)] |
| 640 | #[cfg(not(feature = "_nrf54l"))] | ||
| 552 | pub enum Resistor { | 641 | pub enum Resistor { |
| 553 | /// Bypass resistor ladder | 642 | /// Bypass resistor ladder |
| 554 | BYPASS = 0, | 643 | BYPASS = 0, |
| @@ -560,6 +649,7 @@ pub enum Resistor { | |||
| 560 | VDD1_2 = 3, | 649 | VDD1_2 = 3, |
| 561 | } | 650 | } |
| 562 | 651 | ||
| 652 | #[cfg(not(feature = "_nrf54l"))] | ||
| 563 | impl From<Time> for vals::Tacq { | 653 | impl From<Time> for vals::Tacq { |
| 564 | fn from(time: Time) -> Self { | 654 | fn from(time: Time) -> Self { |
| 565 | match time { | 655 | match time { |
| @@ -573,6 +663,20 @@ impl From<Time> for vals::Tacq { | |||
| 573 | } | 663 | } |
| 574 | } | 664 | } |
| 575 | 665 | ||
| 666 | #[cfg(feature = "_nrf54l")] | ||
| 667 | impl From<Time> for u16 { | ||
| 668 | fn from(time: Time) -> Self { | ||
| 669 | match time { | ||
| 670 | Time::_3US => (3000 / 125) - 1, | ||
| 671 | Time::_5US => (5000 / 125) - 1, | ||
| 672 | Time::_10US => (10000 / 125) - 1, | ||
| 673 | Time::_15US => (15000 / 125) - 1, | ||
| 674 | Time::_20US => (20000 / 125) - 1, | ||
| 675 | Time::_40US => (40000 / 125) - 1, | ||
| 676 | } | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 576 | /// Acquisition time, the time the SAADC uses to sample the input voltage | 680 | /// Acquisition time, the time the SAADC uses to sample the input voltage |
| 577 | #[non_exhaustive] | 681 | #[non_exhaustive] |
| 578 | #[derive(Clone, Copy)] | 682 | #[derive(Clone, Copy)] |
| @@ -657,7 +761,20 @@ pub enum Resolution { | |||
| 657 | } | 761 | } |
| 658 | 762 | ||
| 659 | pub(crate) trait SealedInput { | 763 | pub(crate) trait SealedInput { |
| 764 | #[cfg(not(feature = "_nrf54l"))] | ||
| 660 | fn channel(&self) -> InputChannel; | 765 | fn channel(&self) -> InputChannel; |
| 766 | |||
| 767 | #[cfg(feature = "_nrf54l")] | ||
| 768 | fn pin(&self) -> u8; | ||
| 769 | |||
| 770 | #[cfg(feature = "_nrf54l")] | ||
| 771 | fn port(&self) -> u8; | ||
| 772 | |||
| 773 | #[cfg(feature = "_nrf54l")] | ||
| 774 | fn internal(&self) -> vals::Internal; | ||
| 775 | |||
| 776 | #[cfg(feature = "_nrf54l")] | ||
| 777 | fn connect(&self) -> vals::PselpConnect; | ||
| 661 | } | 778 | } |
| 662 | 779 | ||
| 663 | /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. | 780 | /// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. |
| @@ -667,6 +784,7 @@ pub trait Input: SealedInput + Sized { | |||
| 667 | /// | 784 | /// |
| 668 | /// This allows using several inputs in situations that might require | 785 | /// This allows using several inputs in situations that might require |
| 669 | /// them to be the same type, like putting them in an array. | 786 | /// them to be the same type, like putting them in an array. |
| 787 | #[cfg(not(feature = "_nrf54l"))] | ||
| 670 | fn degrade_saadc<'a>(self) -> AnyInput<'a> | 788 | fn degrade_saadc<'a>(self) -> AnyInput<'a> |
| 671 | where | 789 | where |
| 672 | Self: 'a, | 790 | Self: 'a, |
| @@ -676,17 +794,49 @@ pub trait Input: SealedInput + Sized { | |||
| 676 | _phantom: core::marker::PhantomData, | 794 | _phantom: core::marker::PhantomData, |
| 677 | } | 795 | } |
| 678 | } | 796 | } |
| 797 | |||
| 798 | /// Convert this SAADC input to a type-erased `AnyInput`. | ||
| 799 | /// | ||
| 800 | /// This allows using several inputs in situations that might require | ||
| 801 | /// them to be the same type, like putting them in an array. | ||
| 802 | #[cfg(feature = "_nrf54l")] | ||
| 803 | fn degrade_saadc<'a>(self) -> AnyInput<'a> | ||
| 804 | where | ||
| 805 | Self: 'a, | ||
| 806 | { | ||
| 807 | AnyInput { | ||
| 808 | pin: self.pin(), | ||
| 809 | port: self.port(), | ||
| 810 | internal: self.internal(), | ||
| 811 | connect: self.connect(), | ||
| 812 | _phantom: core::marker::PhantomData, | ||
| 813 | } | ||
| 814 | } | ||
| 679 | } | 815 | } |
| 680 | 816 | ||
| 681 | /// A type-erased SAADC input. | 817 | /// A type-erased SAADC input. |
| 682 | /// | 818 | /// |
| 683 | /// This allows using several inputs in situations that might require | 819 | /// This allows using several inputs in situations that might require |
| 684 | /// them to be the same type, like putting them in an array. | 820 | /// them to be the same type, like putting them in an array. |
| 821 | #[cfg(not(feature = "_nrf54l"))] | ||
| 685 | pub struct AnyInput<'a> { | 822 | pub struct AnyInput<'a> { |
| 686 | channel: InputChannel, | 823 | channel: InputChannel, |
| 687 | _phantom: PhantomData<&'a ()>, | 824 | _phantom: PhantomData<&'a ()>, |
| 688 | } | 825 | } |
| 689 | 826 | ||
| 827 | /// A type-erased SAADC input. | ||
| 828 | /// | ||
| 829 | /// This allows using several inputs in situations that might require | ||
| 830 | /// them to be the same type, like putting them in an array. | ||
| 831 | #[cfg(feature = "_nrf54l")] | ||
| 832 | pub struct AnyInput<'a> { | ||
| 833 | pin: u8, | ||
| 834 | port: u8, | ||
| 835 | internal: vals::Internal, | ||
| 836 | connect: vals::PselpConnect, | ||
| 837 | _phantom: PhantomData<&'a ()>, | ||
| 838 | } | ||
| 839 | |||
| 690 | impl<'a> AnyInput<'a> { | 840 | impl<'a> AnyInput<'a> { |
| 691 | /// Reborrow into a "child" AnyInput. | 841 | /// Reborrow into a "child" AnyInput. |
| 692 | /// | 842 | /// |
| @@ -694,21 +844,56 @@ impl<'a> AnyInput<'a> { | |||
| 694 | pub fn reborrow(&mut self) -> AnyInput<'_> { | 844 | pub fn reborrow(&mut self) -> AnyInput<'_> { |
| 695 | // safety: we're returning the clone inside a new Peripheral that borrows | 845 | // safety: we're returning the clone inside a new Peripheral that borrows |
| 696 | // self, so user code can't use both at the same time. | 846 | // self, so user code can't use both at the same time. |
| 697 | Self { | 847 | #[cfg(not(feature = "_nrf54l"))] |
| 698 | channel: self.channel, | 848 | { |
| 699 | _phantom: PhantomData, | 849 | Self { |
| 850 | channel: self.channel, | ||
| 851 | _phantom: PhantomData, | ||
| 852 | } | ||
| 853 | } | ||
| 854 | #[cfg(feature = "_nrf54l")] | ||
| 855 | { | ||
| 856 | Self { | ||
| 857 | pin: self.pin, | ||
| 858 | port: self.port, | ||
| 859 | internal: self.internal, | ||
| 860 | connect: self.connect, | ||
| 861 | _phantom: PhantomData, | ||
| 862 | } | ||
| 700 | } | 863 | } |
| 701 | } | 864 | } |
| 702 | } | 865 | } |
| 703 | 866 | ||
| 704 | impl SealedInput for AnyInput<'_> { | 867 | impl SealedInput for AnyInput<'_> { |
| 868 | #[cfg(not(feature = "_nrf54l"))] | ||
| 705 | fn channel(&self) -> InputChannel { | 869 | fn channel(&self) -> InputChannel { |
| 706 | self.channel | 870 | self.channel |
| 707 | } | 871 | } |
| 872 | |||
| 873 | #[cfg(feature = "_nrf54l")] | ||
| 874 | fn pin(&self) -> u8 { | ||
| 875 | self.pin | ||
| 876 | } | ||
| 877 | |||
| 878 | #[cfg(feature = "_nrf54l")] | ||
| 879 | fn port(&self) -> u8 { | ||
| 880 | self.port | ||
| 881 | } | ||
| 882 | |||
| 883 | #[cfg(feature = "_nrf54l")] | ||
| 884 | fn internal(&self) -> vals::Internal { | ||
| 885 | self.internal | ||
| 886 | } | ||
| 887 | |||
| 888 | #[cfg(feature = "_nrf54l")] | ||
| 889 | fn connect(&self) -> vals::PselpConnect { | ||
| 890 | self.connect | ||
| 891 | } | ||
| 708 | } | 892 | } |
| 709 | 893 | ||
| 710 | impl Input for AnyInput<'_> {} | 894 | impl Input for AnyInput<'_> {} |
| 711 | 895 | ||
| 896 | #[cfg(not(feature = "_nrf54l"))] | ||
| 712 | macro_rules! impl_saadc_input { | 897 | macro_rules! impl_saadc_input { |
| 713 | ($pin:ident, $ch:ident) => { | 898 | ($pin:ident, $ch:ident) => { |
| 714 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); | 899 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $ch); |
| @@ -723,15 +908,45 @@ macro_rules! impl_saadc_input { | |||
| 723 | }; | 908 | }; |
| 724 | } | 909 | } |
| 725 | 910 | ||
| 911 | #[cfg(feature = "_nrf54l")] | ||
| 912 | macro_rules! impl_saadc_input { | ||
| 913 | ($pin:ident, $port:expr, $ain:expr) => { | ||
| 914 | impl_saadc_input!(@local, crate::Peri<'_, crate::peripherals::$pin>, $port, $ain, AVDD, ANALOG_INPUT); | ||
| 915 | }; | ||
| 916 | (@local, $pin:ty, $port:expr, $ain:expr, $internal:ident, $connect:ident) => { | ||
| 917 | impl crate::saadc::SealedInput for $pin { | ||
| 918 | fn pin(&self) -> u8 { | ||
| 919 | $ain | ||
| 920 | } | ||
| 921 | |||
| 922 | fn port(&self) -> u8 { | ||
| 923 | $port | ||
| 924 | } | ||
| 925 | |||
| 926 | fn internal(&self) -> crate::pac::saadc::vals::Internal { | ||
| 927 | crate::pac::saadc::vals::Internal::$internal | ||
| 928 | } | ||
| 929 | |||
| 930 | fn connect(&self) -> crate::pac::saadc::vals::PselpConnect { | ||
| 931 | crate::pac::saadc::vals::PselpConnect::$connect | ||
| 932 | } | ||
| 933 | } | ||
| 934 | impl crate::saadc::Input for $pin {} | ||
| 935 | }; | ||
| 936 | } | ||
| 937 | |||
| 726 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 938 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 727 | /// internal voltage. | 939 | /// internal voltage. |
| 728 | pub struct VddInput; | 940 | pub struct VddInput; |
| 729 | 941 | ||
| 730 | impl_peripheral!(VddInput); | 942 | impl_peripheral!(VddInput); |
| 943 | #[cfg(not(feature = "_nrf54l"))] | ||
| 731 | #[cfg(not(feature = "_nrf91"))] | 944 | #[cfg(not(feature = "_nrf91"))] |
| 732 | impl_saadc_input!(@local, VddInput, VDD); | 945 | impl_saadc_input!(@local, VddInput, VDD); |
| 733 | #[cfg(feature = "_nrf91")] | 946 | #[cfg(feature = "_nrf91")] |
| 734 | impl_saadc_input!(@local, VddInput, VDD_GPIO); | 947 | impl_saadc_input!(@local, VddInput, VDD_GPIO); |
| 948 | #[cfg(feature = "_nrf54l")] | ||
| 949 | impl_saadc_input!(@local, VddInput, 0, 0, VDD, INTERNAL); | ||
| 735 | 950 | ||
| 736 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | 951 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the |
| 737 | /// VDDH / 5 voltage. | 952 | /// VDDH / 5 voltage. |
| @@ -743,3 +958,21 @@ impl_peripheral!(VddhDiv5Input); | |||
| 743 | 958 | ||
| 744 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | 959 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] |
| 745 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); | 960 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); |
| 961 | |||
| 962 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | ||
| 963 | /// AVDD internal voltage of the nrf54l chip family. | ||
| 964 | #[cfg(feature = "_nrf54l")] | ||
| 965 | pub struct AVddInput; | ||
| 966 | #[cfg(feature = "_nrf54l")] | ||
| 967 | embassy_hal_internal::impl_peripheral!(AVddInput); | ||
| 968 | #[cfg(feature = "_nrf54l")] | ||
| 969 | impl_saadc_input!(@local, AVddInput, 0, 0, AVDD, INTERNAL); | ||
| 970 | |||
| 971 | /// A dummy `Input` pin implementation for SAADC peripheral sampling from the | ||
| 972 | /// DVDD internal voltage of the nrf54l chip family. | ||
| 973 | #[cfg(feature = "_nrf54l")] | ||
| 974 | pub struct DVddInput; | ||
| 975 | #[cfg(feature = "_nrf54l")] | ||
| 976 | embassy_hal_internal::impl_peripheral!(DVddInput); | ||
| 977 | #[cfg(feature = "_nrf54l")] | ||
| 978 | impl_saadc_input!(@local, DVddInput, 0, 0, DVDD, INTERNAL); | ||
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index ce994dbc9..34485609b 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -13,7 +13,7 @@ use embassy_embedded_hal::SetConfig; | |||
| 13 | use embassy_hal_internal::{Peri, PeripheralType}; | 13 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 14 | use embassy_sync::waitqueue::AtomicWaker; | 14 | use embassy_sync::waitqueue::AtomicWaker; |
| 15 | pub use embedded_hal_02::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode, Phase, Polarity}; | 15 | pub use embedded_hal_02::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode, Phase, Polarity}; |
| 16 | pub use pac::spim::vals::{Frequency, Order as BitOrder}; | 16 | pub use pac::spim::vals::Order as BitOrder; |
| 17 | 17 | ||
| 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 19 | use crate::gpio::{self, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; | 19 | use crate::gpio::{self, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; |
| @@ -23,6 +23,110 @@ use crate::pac::spim::vals; | |||
| 23 | use crate::util::slice_in_ram_or; | 23 | use crate::util::slice_in_ram_or; |
| 24 | use crate::{interrupt, pac}; | 24 | use crate::{interrupt, pac}; |
| 25 | 25 | ||
| 26 | /// SPI frequencies. | ||
| 27 | #[repr(transparent)] | ||
| 28 | #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] | ||
| 29 | pub struct Frequency(u32); | ||
| 30 | impl Frequency { | ||
| 31 | #[doc = "125 kbps"] | ||
| 32 | pub const K125: Self = Self(0x0200_0000); | ||
| 33 | #[doc = "250 kbps"] | ||
| 34 | pub const K250: Self = Self(0x0400_0000); | ||
| 35 | #[doc = "500 kbps"] | ||
| 36 | pub const K500: Self = Self(0x0800_0000); | ||
| 37 | #[doc = "1 Mbps"] | ||
| 38 | pub const M1: Self = Self(0x1000_0000); | ||
| 39 | #[doc = "2 Mbps"] | ||
| 40 | pub const M2: Self = Self(0x2000_0000); | ||
| 41 | #[doc = "4 Mbps"] | ||
| 42 | pub const M4: Self = Self(0x4000_0000); | ||
| 43 | #[doc = "8 Mbps"] | ||
| 44 | pub const M8: Self = Self(0x8000_0000); | ||
| 45 | #[cfg(not(feature = "_spi-v1"))] | ||
| 46 | #[doc = "16 Mbps"] | ||
| 47 | pub const M16: Self = Self(0x0a00_0000); | ||
| 48 | #[cfg(not(feature = "_spi-v1"))] | ||
| 49 | #[doc = "32 Mbps"] | ||
| 50 | pub const M32: Self = Self(0x1400_0000); | ||
| 51 | } | ||
| 52 | |||
| 53 | impl Frequency { | ||
| 54 | #[cfg(feature = "_nrf54l")] | ||
| 55 | fn to_divisor(&self, clk: u32) -> u8 { | ||
| 56 | let frequency = match *self { | ||
| 57 | #[cfg(not(feature = "_spi-v1"))] | ||
| 58 | Self::M32 => 32_000_000, | ||
| 59 | #[cfg(not(feature = "_spi-v1"))] | ||
| 60 | Self::M16 => 16_000_000, | ||
| 61 | Self::M8 => 8_000_000, | ||
| 62 | Self::M4 => 4_000_000, | ||
| 63 | Self::M2 => 2_000_000, | ||
| 64 | Self::M1 => 1_000_000, | ||
| 65 | Self::K500 => 500_000, | ||
| 66 | Self::K250 => 250_000, | ||
| 67 | Self::K125 => 125_000, | ||
| 68 | _ => unreachable!(), | ||
| 69 | }; | ||
| 70 | let divisor = (clk / frequency) as u8; | ||
| 71 | divisor | ||
| 72 | } | ||
| 73 | } | ||
| 74 | impl core::fmt::Debug for Frequency { | ||
| 75 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { | ||
| 76 | match self.0 { | ||
| 77 | 0x0200_0000 => f.write_str("K125"), | ||
| 78 | 0x0400_0000 => f.write_str("K250"), | ||
| 79 | 0x0800_0000 => f.write_str("K500"), | ||
| 80 | 0x0a00_0000 => f.write_str("M16"), | ||
| 81 | 0x1000_0000 => f.write_str("M1"), | ||
| 82 | 0x1400_0000 => f.write_str("M32"), | ||
| 83 | 0x2000_0000 => f.write_str("M2"), | ||
| 84 | 0x4000_0000 => f.write_str("M4"), | ||
| 85 | 0x8000_0000 => f.write_str("M8"), | ||
| 86 | other => core::write!(f, "0x{:02X}", other), | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | #[cfg(feature = "defmt")] | ||
| 92 | impl defmt::Format for Frequency { | ||
| 93 | fn format(&self, f: defmt::Formatter) { | ||
| 94 | match self.0 { | ||
| 95 | 0x0200_0000 => defmt::write!(f, "K125"), | ||
| 96 | 0x0400_0000 => defmt::write!(f, "K250"), | ||
| 97 | 0x0800_0000 => defmt::write!(f, "K500"), | ||
| 98 | 0x0a00_0000 => defmt::write!(f, "M16"), | ||
| 99 | 0x1000_0000 => defmt::write!(f, "M1"), | ||
| 100 | 0x1400_0000 => defmt::write!(f, "M32"), | ||
| 101 | 0x2000_0000 => defmt::write!(f, "M2"), | ||
| 102 | 0x4000_0000 => defmt::write!(f, "M4"), | ||
| 103 | 0x8000_0000 => defmt::write!(f, "M8"), | ||
| 104 | other => defmt::write!(f, "0x{:02X}", other), | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | #[cfg(not(feature = "_nrf54l"))] | ||
| 110 | impl Into<pac::spim::vals::Frequency> for Frequency { | ||
| 111 | fn into(self) -> pac::spim::vals::Frequency { | ||
| 112 | use pac::spim::vals::Frequency as Freq; | ||
| 113 | match self { | ||
| 114 | #[cfg(not(feature = "_spi-v1"))] | ||
| 115 | Self::M32 => Freq::M32, | ||
| 116 | #[cfg(not(feature = "_spi-v1"))] | ||
| 117 | Self::M16 => Freq::M16, | ||
| 118 | Self::M8 => Freq::M8, | ||
| 119 | Self::M4 => Freq::M4, | ||
| 120 | Self::M2 => Freq::M2, | ||
| 121 | Self::M1 => Freq::M1, | ||
| 122 | Self::K500 => Freq::K500, | ||
| 123 | Self::K250 => Freq::K250, | ||
| 124 | Self::K125 => Freq::K125, | ||
| 125 | _ => unreachable!(), | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 26 | /// SPIM error | 130 | /// SPIM error |
| 27 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 131 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 28 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 132 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -103,6 +207,8 @@ pub struct Spim<'d> { | |||
| 103 | r: pac::spim::Spim, | 207 | r: pac::spim::Spim, |
| 104 | irq: interrupt::Interrupt, | 208 | irq: interrupt::Interrupt, |
| 105 | state: &'static State, | 209 | state: &'static State, |
| 210 | #[cfg(feature = "_nrf54l")] | ||
| 211 | clk: u32, | ||
| 106 | _p: PhantomData<&'d ()>, | 212 | _p: PhantomData<&'d ()>, |
| 107 | } | 213 | } |
| 108 | 214 | ||
| @@ -208,6 +314,8 @@ impl<'d> Spim<'d> { | |||
| 208 | r: T::regs(), | 314 | r: T::regs(), |
| 209 | irq: T::Interrupt::IRQ, | 315 | irq: T::Interrupt::IRQ, |
| 210 | state: T::state(), | 316 | state: T::state(), |
| 317 | #[cfg(feature = "_nrf54l")] | ||
| 318 | clk: T::clk(), | ||
| 211 | _p: PhantomData {}, | 319 | _p: PhantomData {}, |
| 212 | }; | 320 | }; |
| 213 | 321 | ||
| @@ -238,13 +346,13 @@ impl<'d> Spim<'d> { | |||
| 238 | 346 | ||
| 239 | // Set up the DMA read. | 347 | // Set up the DMA read. |
| 240 | let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length); | 348 | let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length); |
| 241 | r.rxd().ptr().write_value(rx_ptr); | 349 | r.dma().rx().ptr().write_value(rx_ptr); |
| 242 | r.rxd().maxcnt().write(|w| w.set_maxcnt(rx_len as _)); | 350 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(rx_len as _)); |
| 243 | 351 | ||
| 244 | // Set up the DMA write. | 352 | // Set up the DMA write. |
| 245 | let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length); | 353 | let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length); |
| 246 | r.txd().ptr().write_value(tx_ptr); | 354 | r.dma().tx().ptr().write_value(tx_ptr); |
| 247 | r.txd().maxcnt().write(|w| w.set_maxcnt(tx_len as _)); | 355 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(tx_len as _)); |
| 248 | 356 | ||
| 249 | /* | 357 | /* |
| 250 | trace!("XFER: offset: {}, length: {}", offset, length); | 358 | trace!("XFER: offset: {}, length: {}", offset, length); |
| @@ -259,8 +367,8 @@ impl<'d> Spim<'d> { | |||
| 259 | r.events_started().write_value(0); | 367 | r.events_started().write_value(0); |
| 260 | 368 | ||
| 261 | // Set rx/tx buffer lengths to 0... | 369 | // Set rx/tx buffer lengths to 0... |
| 262 | r.txd().maxcnt().write(|_| ()); | 370 | r.dma().tx().maxcnt().write(|_| ()); |
| 263 | r.rxd().maxcnt().write(|_| ()); | 371 | r.dma().rx().maxcnt().write(|_| ()); |
| 264 | 372 | ||
| 265 | // ...and keep track of original buffer lengths... | 373 | // ...and keep track of original buffer lengths... |
| 266 | s.tx.store(tx_len as _, Ordering::Relaxed); | 374 | s.tx.store(tx_len as _, Ordering::Relaxed); |
| @@ -447,8 +555,14 @@ impl<'d> Spim<'d> { | |||
| 447 | r.events_end().write_value(0); | 555 | r.events_end().write_value(0); |
| 448 | 556 | ||
| 449 | // Update DMA registers with correct rx/tx buffer sizes | 557 | // Update DMA registers with correct rx/tx buffer sizes |
| 450 | r.rxd().maxcnt().write(|w| w.set_maxcnt(s.rx.load(Ordering::Relaxed))); | 558 | r.dma() |
| 451 | r.txd().maxcnt().write(|w| w.set_maxcnt(s.tx.load(Ordering::Relaxed))); | 559 | .rx() |
| 560 | .maxcnt() | ||
| 561 | .write(|w| w.set_maxcnt(s.rx.load(Ordering::Relaxed))); | ||
| 562 | r.dma() | ||
| 563 | .tx() | ||
| 564 | .maxcnt() | ||
| 565 | .write(|w| w.set_maxcnt(s.tx.load(Ordering::Relaxed))); | ||
| 452 | 566 | ||
| 453 | r.intenset().write(|w| w.set_end(true)); | 567 | r.intenset().write(|w| w.set_end(true)); |
| 454 | // ... and start actual, hopefully glitch-free transmission | 568 | // ... and start actual, hopefully glitch-free transmission |
| @@ -503,6 +617,8 @@ impl State { | |||
| 503 | pub(crate) trait SealedInstance { | 617 | pub(crate) trait SealedInstance { |
| 504 | fn regs() -> pac::spim::Spim; | 618 | fn regs() -> pac::spim::Spim; |
| 505 | fn state() -> &'static State; | 619 | fn state() -> &'static State; |
| 620 | #[cfg(feature = "_nrf54l")] | ||
| 621 | fn clk() -> u32; | ||
| 506 | } | 622 | } |
| 507 | 623 | ||
| 508 | /// SPIM peripheral instance | 624 | /// SPIM peripheral instance |
| @@ -512,6 +628,28 @@ pub trait Instance: SealedInstance + PeripheralType + 'static { | |||
| 512 | type Interrupt: interrupt::typelevel::Interrupt; | 628 | type Interrupt: interrupt::typelevel::Interrupt; |
| 513 | } | 629 | } |
| 514 | 630 | ||
| 631 | #[cfg(feature = "_nrf54l")] | ||
| 632 | macro_rules! impl_spim { | ||
| 633 | ($type:ident, $pac_type:ident, $irq:ident, $clk:expr) => { | ||
| 634 | impl crate::spim::SealedInstance for peripherals::$type { | ||
| 635 | fn regs() -> pac::spim::Spim { | ||
| 636 | pac::$pac_type | ||
| 637 | } | ||
| 638 | fn state() -> &'static crate::spim::State { | ||
| 639 | static STATE: crate::spim::State = crate::spim::State::new(); | ||
| 640 | &STATE | ||
| 641 | } | ||
| 642 | fn clk() -> u32 { | ||
| 643 | $clk | ||
| 644 | } | ||
| 645 | } | ||
| 646 | impl crate::spim::Instance for peripherals::$type { | ||
| 647 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 648 | } | ||
| 649 | }; | ||
| 650 | } | ||
| 651 | |||
| 652 | #[cfg(not(feature = "_nrf54l"))] | ||
| 515 | macro_rules! impl_spim { | 653 | macro_rules! impl_spim { |
| 516 | ($type:ident, $pac_type:ident, $irq:ident) => { | 654 | ($type:ident, $pac_type:ident, $irq:ident) => { |
| 517 | impl crate::spim::SealedInstance for peripherals::$type { | 655 | impl crate::spim::SealedInstance for peripherals::$type { |
| @@ -638,7 +776,12 @@ impl<'d> SetConfig for Spim<'d> { | |||
| 638 | 776 | ||
| 639 | // Configure frequency. | 777 | // Configure frequency. |
| 640 | let frequency = config.frequency; | 778 | let frequency = config.frequency; |
| 641 | r.frequency().write(|w| w.set_frequency(frequency)); | 779 | #[cfg(not(feature = "_nrf54l"))] |
| 780 | r.frequency().write(|w| w.set_frequency(frequency.into())); | ||
| 781 | #[cfg(feature = "_nrf54l")] | ||
| 782 | { | ||
| 783 | r.prescaler().write(|w| w.set_divisor(frequency.to_divisor(self.clk))); | ||
| 784 | } | ||
| 642 | 785 | ||
| 643 | // Set over-read character | 786 | // Set over-read character |
| 644 | let orc = config.orc; | 787 | let orc = config.orc; |
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 885821146..96a9c0ae0 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -224,15 +224,15 @@ impl<'d> Spis<'d> { | |||
| 224 | if tx.len() > EASY_DMA_SIZE { | 224 | if tx.len() > EASY_DMA_SIZE { |
| 225 | return Err(Error::TxBufferTooLong); | 225 | return Err(Error::TxBufferTooLong); |
| 226 | } | 226 | } |
| 227 | r.txd().ptr().write_value(tx as *const u8 as _); | 227 | r.dma().tx().ptr().write_value(tx as *const u8 as _); |
| 228 | r.txd().maxcnt().write(|w| w.set_maxcnt(tx.len() as _)); | 228 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(tx.len() as _)); |
| 229 | 229 | ||
| 230 | // Set up the DMA read. | 230 | // Set up the DMA read. |
| 231 | if rx.len() > EASY_DMA_SIZE { | 231 | if rx.len() > EASY_DMA_SIZE { |
| 232 | return Err(Error::RxBufferTooLong); | 232 | return Err(Error::RxBufferTooLong); |
| 233 | } | 233 | } |
| 234 | r.rxd().ptr().write_value(rx as *mut u8 as _); | 234 | r.dma().rx().ptr().write_value(rx as *mut u8 as _); |
| 235 | r.rxd().maxcnt().write(|w| w.set_maxcnt(rx.len() as _)); | 235 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(rx.len() as _)); |
| 236 | 236 | ||
| 237 | // Reset end event. | 237 | // Reset end event. |
| 238 | r.events_end().write_value(0); | 238 | r.events_end().write_value(0); |
| @@ -260,8 +260,8 @@ impl<'d> Spis<'d> { | |||
| 260 | // Wait for 'end' event. | 260 | // Wait for 'end' event. |
| 261 | while r.events_end().read() == 0 {} | 261 | while r.events_end().read() == 0 {} |
| 262 | 262 | ||
| 263 | let n_rx = r.rxd().amount().read().0 as usize; | 263 | let n_rx = r.dma().rx().amount().read().0 as usize; |
| 264 | let n_tx = r.txd().amount().read().0 as usize; | 264 | let n_tx = r.dma().tx().amount().read().0 as usize; |
| 265 | 265 | ||
| 266 | compiler_fence(Ordering::SeqCst); | 266 | compiler_fence(Ordering::SeqCst); |
| 267 | 267 | ||
| @@ -326,8 +326,8 @@ impl<'d> Spis<'d> { | |||
| 326 | }) | 326 | }) |
| 327 | .await; | 327 | .await; |
| 328 | 328 | ||
| 329 | let n_rx = r.rxd().amount().read().0 as usize; | 329 | let n_rx = r.dma().rx().amount().read().0 as usize; |
| 330 | let n_tx = r.txd().amount().read().0 as usize; | 330 | let n_tx = r.dma().tx().amount().read().0 as usize; |
| 331 | 331 | ||
| 332 | compiler_fence(Ordering::SeqCst); | 332 | compiler_fence(Ordering::SeqCst); |
| 333 | 333 | ||
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 93255c832..abf9a923f 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -141,10 +141,19 @@ impl<'d> Twim<'d> { | |||
| 141 | sda.conf().write(|w| { | 141 | sda.conf().write(|w| { |
| 142 | w.set_dir(gpiovals::Dir::OUTPUT); | 142 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 143 | w.set_input(gpiovals::Input::CONNECT); | 143 | w.set_input(gpiovals::Input::CONNECT); |
| 144 | #[cfg(not(feature = "_nrf54l"))] | ||
| 144 | w.set_drive(match config.sda_high_drive { | 145 | w.set_drive(match config.sda_high_drive { |
| 145 | true => gpiovals::Drive::H0D1, | 146 | true => gpiovals::Drive::H0D1, |
| 146 | false => gpiovals::Drive::S0D1, | 147 | false => gpiovals::Drive::S0D1, |
| 147 | }); | 148 | }); |
| 149 | #[cfg(feature = "_nrf54l")] | ||
| 150 | { | ||
| 151 | w.set_drive0(match config.sda_high_drive { | ||
| 152 | true => gpiovals::Drive::H, | ||
| 153 | false => gpiovals::Drive::S, | ||
| 154 | }); | ||
| 155 | w.set_drive1(gpiovals::Drive::D); | ||
| 156 | } | ||
| 148 | if config.sda_pullup { | 157 | if config.sda_pullup { |
| 149 | w.set_pull(gpiovals::Pull::PULLUP); | 158 | w.set_pull(gpiovals::Pull::PULLUP); |
| 150 | } | 159 | } |
| @@ -152,10 +161,19 @@ impl<'d> Twim<'d> { | |||
| 152 | scl.conf().write(|w| { | 161 | scl.conf().write(|w| { |
| 153 | w.set_dir(gpiovals::Dir::OUTPUT); | 162 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 154 | w.set_input(gpiovals::Input::CONNECT); | 163 | w.set_input(gpiovals::Input::CONNECT); |
| 164 | #[cfg(not(feature = "_nrf54l"))] | ||
| 155 | w.set_drive(match config.scl_high_drive { | 165 | w.set_drive(match config.scl_high_drive { |
| 156 | true => gpiovals::Drive::H0D1, | 166 | true => gpiovals::Drive::H0D1, |
| 157 | false => gpiovals::Drive::S0D1, | 167 | false => gpiovals::Drive::S0D1, |
| 158 | }); | 168 | }); |
| 169 | #[cfg(feature = "_nrf54l")] | ||
| 170 | { | ||
| 171 | w.set_drive0(match config.scl_high_drive { | ||
| 172 | true => gpiovals::Drive::H, | ||
| 173 | false => gpiovals::Drive::S, | ||
| 174 | }); | ||
| 175 | w.set_drive1(gpiovals::Drive::D); | ||
| 176 | } | ||
| 159 | if config.sda_pullup { | 177 | if config.sda_pullup { |
| 160 | w.set_pull(gpiovals::Pull::PULLUP); | 178 | w.set_pull(gpiovals::Pull::PULLUP); |
| 161 | } | 179 | } |
| @@ -210,8 +228,8 @@ impl<'d> Twim<'d> { | |||
| 210 | // We're giving the register a pointer to the stack. Since we're | 228 | // We're giving the register a pointer to the stack. Since we're |
| 211 | // waiting for the I2C transaction to end before this stack pointer | 229 | // waiting for the I2C transaction to end before this stack pointer |
| 212 | // becomes invalid, there's nothing wrong here. | 230 | // becomes invalid, there's nothing wrong here. |
| 213 | r.txd().ptr().write_value(buffer.as_ptr() as u32); | 231 | r.dma().tx().ptr().write_value(buffer.as_ptr() as u32); |
| 214 | r.txd().maxcnt().write(|w| | 232 | r.dma().tx().maxcnt().write(|w| |
| 215 | // We're giving it the length of the buffer, so no danger of | 233 | // We're giving it the length of the buffer, so no danger of |
| 216 | // accessing invalid memory. We have verified that the length of the | 234 | // accessing invalid memory. We have verified that the length of the |
| 217 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | 235 | // buffer fits in an `u8`, so the cast to `u8` is also fine. |
| @@ -237,8 +255,8 @@ impl<'d> Twim<'d> { | |||
| 237 | // 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 |
| 238 | // waiting for the I2C transaction to end before this stack pointer | 256 | // waiting for the I2C transaction to end before this stack pointer |
| 239 | // becomes invalid, there's nothing wrong here. | 257 | // becomes invalid, there's nothing wrong here. |
| 240 | r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32); | 258 | r.dma().rx().ptr().write_value(buffer.as_mut_ptr() as u32); |
| 241 | r.rxd().maxcnt().write(|w| | 259 | r.dma().rx().maxcnt().write(|w| |
| 242 | // We're giving it the length of the buffer, so no danger of | 260 | // We're giving it the length of the buffer, so no danger of |
| 243 | // accessing invalid memory. We have verified that the length of the | 261 | // accessing invalid memory. We have verified that the length of the |
| 244 | // buffer fits in an `u8`, so the cast to the type of maxcnt | 262 | // buffer fits in an `u8`, so the cast to the type of maxcnt |
| @@ -281,7 +299,7 @@ impl<'d> Twim<'d> { | |||
| 281 | 299 | ||
| 282 | fn check_rx(&self, len: usize) -> Result<(), Error> { | 300 | fn check_rx(&self, len: usize) -> Result<(), Error> { |
| 283 | let r = self.r; | 301 | let r = self.r; |
| 284 | if r.rxd().amount().read().0 != len as u32 { | 302 | if r.dma().rx().amount().read().0 != len as u32 { |
| 285 | Err(Error::Receive) | 303 | Err(Error::Receive) |
| 286 | } else { | 304 | } else { |
| 287 | Ok(()) | 305 | Ok(()) |
| @@ -290,7 +308,7 @@ impl<'d> Twim<'d> { | |||
| 290 | 308 | ||
| 291 | fn check_tx(&self, len: usize) -> Result<(), Error> { | 309 | fn check_tx(&self, len: usize) -> Result<(), Error> { |
| 292 | let r = self.r; | 310 | let r = self.r; |
| 293 | if r.txd().amount().read().0 != len as u32 { | 311 | if r.dma().tx().amount().read().0 != len as u32 { |
| 294 | Err(Error::Transmit) | 312 | Err(Error::Transmit) |
| 295 | } else { | 313 | } else { |
| 296 | Ok(()) | 314 | Ok(()) |
| @@ -412,7 +430,7 @@ impl<'d> Twim<'d> { | |||
| 412 | } | 430 | } |
| 413 | 431 | ||
| 414 | r.shorts().write(|w| { | 432 | r.shorts().write(|w| { |
| 415 | w.set_lastrx_starttx(true); | 433 | w.set_lastrx_dma_tx_start(true); |
| 416 | if stop { | 434 | if stop { |
| 417 | w.set_lasttx_stop(true); | 435 | w.set_lasttx_stop(true); |
| 418 | } else { | 436 | } else { |
| @@ -421,7 +439,7 @@ impl<'d> Twim<'d> { | |||
| 421 | }); | 439 | }); |
| 422 | 440 | ||
| 423 | // Start read+write operation. | 441 | // Start read+write operation. |
| 424 | r.tasks_startrx().write_value(1); | 442 | r.tasks_dma().rx().start().write_value(1); |
| 425 | if last_op.is_some() { | 443 | if last_op.is_some() { |
| 426 | r.tasks_resume().write_value(1); | 444 | r.tasks_resume().write_value(1); |
| 427 | } | 445 | } |
| @@ -429,7 +447,7 @@ impl<'d> Twim<'d> { | |||
| 429 | // TODO: Handle empty write buffer | 447 | // TODO: Handle empty write buffer |
| 430 | if rd_buffer.is_empty() { | 448 | if rd_buffer.is_empty() { |
| 431 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves. | 449 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STARTTX ourselves. |
| 432 | r.tasks_starttx().write_value(1); | 450 | r.tasks_dma().tx().start().write_value(1); |
| 433 | } | 451 | } |
| 434 | 452 | ||
| 435 | Ok(2) | 453 | Ok(2) |
| @@ -443,7 +461,7 @@ impl<'d> Twim<'d> { | |||
| 443 | r.shorts().write(|w| w.set_lastrx_stop(true)); | 461 | r.shorts().write(|w| w.set_lastrx_stop(true)); |
| 444 | 462 | ||
| 445 | // Start read operation. | 463 | // Start read operation. |
| 446 | r.tasks_startrx().write_value(1); | 464 | r.tasks_dma().rx().start().write_value(1); |
| 447 | if last_op.is_some() { | 465 | if last_op.is_some() { |
| 448 | r.tasks_resume().write_value(1); | 466 | r.tasks_resume().write_value(1); |
| 449 | } | 467 | } |
| @@ -466,11 +484,11 @@ impl<'d> Twim<'d> { | |||
| 466 | 484 | ||
| 467 | // Start write+read operation. | 485 | // Start write+read operation. |
| 468 | r.shorts().write(|w| { | 486 | r.shorts().write(|w| { |
| 469 | w.set_lasttx_startrx(true); | 487 | w.set_lasttx_dma_rx_start(true); |
| 470 | w.set_lastrx_stop(true); | 488 | w.set_lastrx_stop(true); |
| 471 | }); | 489 | }); |
| 472 | 490 | ||
| 473 | r.tasks_starttx().write_value(1); | 491 | r.tasks_dma().tx().start().write_value(1); |
| 474 | if last_op.is_some() { | 492 | if last_op.is_some() { |
| 475 | r.tasks_resume().write_value(1); | 493 | r.tasks_resume().write_value(1); |
| 476 | } | 494 | } |
| @@ -494,7 +512,7 @@ impl<'d> Twim<'d> { | |||
| 494 | } | 512 | } |
| 495 | }); | 513 | }); |
| 496 | 514 | ||
| 497 | r.tasks_starttx().write_value(1); | 515 | r.tasks_dma().tx().start().write_value(1); |
| 498 | if last_op.is_some() { | 516 | if last_op.is_some() { |
| 499 | r.tasks_resume().write_value(1); | 517 | r.tasks_resume().write_value(1); |
| 500 | } | 518 | } |
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index 2bc0a5c13..b3a699f71 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs | |||
| @@ -161,10 +161,19 @@ impl<'d> Twis<'d> { | |||
| 161 | sda.conf().write(|w| { | 161 | sda.conf().write(|w| { |
| 162 | w.set_dir(gpiovals::Dir::INPUT); | 162 | w.set_dir(gpiovals::Dir::INPUT); |
| 163 | w.set_input(gpiovals::Input::CONNECT); | 163 | w.set_input(gpiovals::Input::CONNECT); |
| 164 | #[cfg(not(feature = "_nrf54l"))] | ||
| 164 | w.set_drive(match config.sda_high_drive { | 165 | w.set_drive(match config.sda_high_drive { |
| 165 | true => gpiovals::Drive::H0D1, | 166 | true => gpiovals::Drive::H0D1, |
| 166 | false => gpiovals::Drive::S0D1, | 167 | false => gpiovals::Drive::S0D1, |
| 167 | }); | 168 | }); |
| 169 | #[cfg(feature = "_nrf54l")] | ||
| 170 | { | ||
| 171 | w.set_drive0(match config.sda_high_drive { | ||
| 172 | true => gpiovals::Drive::H, | ||
| 173 | false => gpiovals::Drive::S, | ||
| 174 | }); | ||
| 175 | w.set_drive1(gpiovals::Drive::D); | ||
| 176 | } | ||
| 168 | if config.sda_pullup { | 177 | if config.sda_pullup { |
| 169 | w.set_pull(gpiovals::Pull::PULLUP); | 178 | w.set_pull(gpiovals::Pull::PULLUP); |
| 170 | } | 179 | } |
| @@ -172,10 +181,19 @@ impl<'d> Twis<'d> { | |||
| 172 | scl.conf().write(|w| { | 181 | scl.conf().write(|w| { |
| 173 | w.set_dir(gpiovals::Dir::INPUT); | 182 | w.set_dir(gpiovals::Dir::INPUT); |
| 174 | w.set_input(gpiovals::Input::CONNECT); | 183 | w.set_input(gpiovals::Input::CONNECT); |
| 184 | #[cfg(not(feature = "_nrf54l"))] | ||
| 175 | w.set_drive(match config.scl_high_drive { | 185 | w.set_drive(match config.scl_high_drive { |
| 176 | true => gpiovals::Drive::H0D1, | 186 | true => gpiovals::Drive::H0D1, |
| 177 | false => gpiovals::Drive::S0D1, | 187 | false => gpiovals::Drive::S0D1, |
| 178 | }); | 188 | }); |
| 189 | #[cfg(feature = "_nrf54l")] | ||
| 190 | { | ||
| 191 | w.set_drive0(match config.scl_high_drive { | ||
| 192 | true => gpiovals::Drive::H, | ||
| 193 | false => gpiovals::Drive::S, | ||
| 194 | }); | ||
| 195 | w.set_drive1(gpiovals::Drive::D); | ||
| 196 | } | ||
| 179 | if config.sda_pullup { | 197 | if config.sda_pullup { |
| 180 | w.set_pull(gpiovals::Pull::PULLUP); | 198 | w.set_pull(gpiovals::Pull::PULLUP); |
| 181 | } | 199 | } |
| @@ -228,8 +246,8 @@ impl<'d> Twis<'d> { | |||
| 228 | // 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 |
| 229 | // waiting for the I2C transaction to end before this stack pointer | 247 | // waiting for the I2C transaction to end before this stack pointer |
| 230 | // becomes invalid, there's nothing wrong here. | 248 | // becomes invalid, there's nothing wrong here. |
| 231 | r.txd().ptr().write_value(buffer.as_ptr() as u32); | 249 | r.dma().tx().ptr().write_value(buffer.as_ptr() as u32); |
| 232 | r.txd().maxcnt().write(|w| | 250 | r.dma().tx().maxcnt().write(|w| |
| 233 | // We're giving it the length of the buffer, so no danger of | 251 | // We're giving it the length of the buffer, so no danger of |
| 234 | // accessing invalid memory. We have verified that the length of the | 252 | // accessing invalid memory. We have verified that the length of the |
| 235 | // buffer fits in an `u8`, so the cast to `u8` is also fine. | 253 | // buffer fits in an `u8`, so the cast to `u8` is also fine. |
| @@ -255,8 +273,8 @@ impl<'d> Twis<'d> { | |||
| 255 | // We're giving the register a pointer to the stack. Since we're | 273 | // We're giving the register a pointer to the stack. Since we're |
| 256 | // waiting for the I2C transaction to end before this stack pointer | 274 | // waiting for the I2C transaction to end before this stack pointer |
| 257 | // becomes invalid, there's nothing wrong here. | 275 | // becomes invalid, there's nothing wrong here. |
| 258 | r.rxd().ptr().write_value(buffer.as_mut_ptr() as u32); | 276 | r.dma().rx().ptr().write_value(buffer.as_mut_ptr() as u32); |
| 259 | r.rxd().maxcnt().write(|w| | 277 | r.dma().rx().maxcnt().write(|w| |
| 260 | // We're giving it the length of the buffer, so no danger of | 278 | // We're giving it the length of the buffer, so no danger of |
| 261 | // accessing invalid memory. We have verified that the length of the | 279 | // accessing invalid memory. We have verified that the length of the |
| 262 | // buffer fits in an `u8`, so the cast to the type of maxcnt | 280 | // buffer fits in an `u8`, so the cast to the type of maxcnt |
| @@ -330,13 +348,13 @@ impl<'d> Twis<'d> { | |||
| 330 | return match status { | 348 | return match status { |
| 331 | Status::Read => Ok(Command::Read), | 349 | Status::Read => Ok(Command::Read), |
| 332 | Status::Write => { | 350 | Status::Write => { |
| 333 | let n = r.rxd().amount().read().0 as usize; | 351 | let n = r.dma().rx().amount().read().0 as usize; |
| 334 | Ok(Command::Write(n)) | 352 | Ok(Command::Write(n)) |
| 335 | } | 353 | } |
| 336 | }; | 354 | }; |
| 337 | } else if r.events_read().read() != 0 { | 355 | } else if r.events_read().read() != 0 { |
| 338 | r.events_read().write_value(0); | 356 | r.events_read().write_value(0); |
| 339 | let n = r.rxd().amount().read().0 as usize; | 357 | let n = r.dma().rx().amount().read().0 as usize; |
| 340 | return Ok(Command::WriteRead(n)); | 358 | return Ok(Command::WriteRead(n)); |
| 341 | } | 359 | } |
| 342 | } | 360 | } |
| @@ -360,7 +378,7 @@ impl<'d> Twis<'d> { | |||
| 360 | } | 378 | } |
| 361 | } else if r.events_stopped().read() != 0 { | 379 | } else if r.events_stopped().read() != 0 { |
| 362 | r.events_stopped().write_value(0); | 380 | r.events_stopped().write_value(0); |
| 363 | let n = r.txd().amount().read().0 as usize; | 381 | let n = r.dma().tx().amount().read().0 as usize; |
| 364 | return Ok(n); | 382 | return Ok(n); |
| 365 | } | 383 | } |
| 366 | } | 384 | } |
| @@ -386,7 +404,7 @@ impl<'d> Twis<'d> { | |||
| 386 | } | 404 | } |
| 387 | } else if r.events_stopped().read() != 0 { | 405 | } else if r.events_stopped().read() != 0 { |
| 388 | r.events_stopped().write_value(0); | 406 | r.events_stopped().write_value(0); |
| 389 | let n = r.txd().amount().read().0 as usize; | 407 | let n = r.dma().tx().amount().read().0 as usize; |
| 390 | return Ok(n); | 408 | return Ok(n); |
| 391 | } else if Instant::now() > deadline { | 409 | } else if Instant::now() > deadline { |
| 392 | r.tasks_stop().write_value(1); | 410 | r.tasks_stop().write_value(1); |
| @@ -442,13 +460,13 @@ impl<'d> Twis<'d> { | |||
| 442 | return match status { | 460 | return match status { |
| 443 | Status::Read => Ok(Command::Read), | 461 | Status::Read => Ok(Command::Read), |
| 444 | Status::Write => { | 462 | Status::Write => { |
| 445 | let n = r.rxd().amount().read().0 as usize; | 463 | let n = r.dma().rx().amount().read().0 as usize; |
| 446 | Ok(Command::Write(n)) | 464 | Ok(Command::Write(n)) |
| 447 | } | 465 | } |
| 448 | }; | 466 | }; |
| 449 | } else if r.events_read().read() != 0 { | 467 | } else if r.events_read().read() != 0 { |
| 450 | r.events_read().write_value(0); | 468 | r.events_read().write_value(0); |
| 451 | let n = r.rxd().amount().read().0 as usize; | 469 | let n = r.dma().rx().amount().read().0 as usize; |
| 452 | return Ok(Command::WriteRead(n)); | 470 | return Ok(Command::WriteRead(n)); |
| 453 | } else if Instant::now() > deadline { | 471 | } else if Instant::now() > deadline { |
| 454 | r.tasks_stop().write_value(1); | 472 | r.tasks_stop().write_value(1); |
| @@ -478,7 +496,7 @@ impl<'d> Twis<'d> { | |||
| 478 | } | 496 | } |
| 479 | } else if r.events_stopped().read() != 0 { | 497 | } else if r.events_stopped().read() != 0 { |
| 480 | r.events_stopped().write_value(0); | 498 | r.events_stopped().write_value(0); |
| 481 | let n = r.txd().amount().read().0 as usize; | 499 | let n = r.dma().tx().amount().read().0 as usize; |
| 482 | return Poll::Ready(Ok(n)); | 500 | return Poll::Ready(Ok(n)); |
| 483 | } | 501 | } |
| 484 | 502 | ||
| @@ -529,13 +547,13 @@ impl<'d> Twis<'d> { | |||
| 529 | return match status { | 547 | return match status { |
| 530 | Status::Read => Poll::Ready(Ok(Command::Read)), | 548 | Status::Read => Poll::Ready(Ok(Command::Read)), |
| 531 | Status::Write => { | 549 | Status::Write => { |
| 532 | let n = r.rxd().amount().read().0 as usize; | 550 | let n = r.dma().rx().amount().read().0 as usize; |
| 533 | Poll::Ready(Ok(Command::Write(n))) | 551 | Poll::Ready(Ok(Command::Write(n))) |
| 534 | } | 552 | } |
| 535 | }; | 553 | }; |
| 536 | } else if r.events_read().read() != 0 { | 554 | } else if r.events_read().read() != 0 { |
| 537 | r.events_read().write_value(0); | 555 | r.events_read().write_value(0); |
| 538 | let n = r.rxd().amount().read().0 as usize; | 556 | let n = r.dma().rx().amount().read().0 as usize; |
| 539 | return Poll::Ready(Ok(Command::WriteRead(n))); | 557 | return Poll::Ready(Ok(Command::WriteRead(n))); |
| 540 | } | 558 | } |
| 541 | Poll::Pending | 559 | Poll::Pending |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 1ee452173..bf3b73f58 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -113,20 +113,20 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 113 | let r = T::regs(); | 113 | let r = T::regs(); |
| 114 | let s = T::state(); | 114 | let s = T::state(); |
| 115 | 115 | ||
| 116 | let endrx = r.events_endrx().read(); | 116 | let endrx = r.events_dma().rx().end().read(); |
| 117 | let error = r.events_error().read(); | 117 | let error = r.events_error().read(); |
| 118 | if endrx != 0 || error != 0 { | 118 | if endrx != 0 || error != 0 { |
| 119 | s.rx_waker.wake(); | 119 | s.rx_waker.wake(); |
| 120 | if endrx != 0 { | 120 | if endrx != 0 { |
| 121 | r.intenclr().write(|w| w.set_endrx(true)); | 121 | r.intenclr().write(|w| w.set_dmarxend(true)); |
| 122 | } | 122 | } |
| 123 | if error != 0 { | 123 | if error != 0 { |
| 124 | r.intenclr().write(|w| w.set_error(true)); | 124 | r.intenclr().write(|w| w.set_error(true)); |
| 125 | } | 125 | } |
| 126 | } | 126 | } |
| 127 | if r.events_endtx().read() != 0 { | 127 | if r.events_dma().tx().end().read() != 0 { |
| 128 | s.tx_waker.wake(); | 128 | s.tx_waker.wake(); |
| 129 | r.intenclr().write(|w| w.set_endtx(true)); | 129 | r.intenclr().write(|w| w.set_dmatxend(true)); |
| 130 | } | 130 | } |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
| @@ -257,7 +257,7 @@ impl<'d> Uarte<'d> { | |||
| 257 | /// Return the endtx event for use with PPI | 257 | /// Return the endtx event for use with PPI |
| 258 | pub fn event_endtx(&self) -> Event<'_> { | 258 | pub fn event_endtx(&self) -> Event<'_> { |
| 259 | let r = self.tx.r; | 259 | let r = self.tx.r; |
| 260 | Event::from_reg(r.events_endtx()) | 260 | Event::from_reg(r.events_dma().tx().end()) |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | /// Read bytes until the buffer is filled. | 263 | /// Read bytes until the buffer is filled. |
| @@ -296,7 +296,13 @@ pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts | |||
| 296 | txd.conf().write(|w| { | 296 | txd.conf().write(|w| { |
| 297 | w.set_dir(gpiovals::Dir::OUTPUT); | 297 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 298 | w.set_input(gpiovals::Input::DISCONNECT); | 298 | w.set_input(gpiovals::Input::DISCONNECT); |
| 299 | #[cfg(not(feature = "_nrf54l"))] | ||
| 299 | w.set_drive(gpiovals::Drive::H0H1); | 300 | w.set_drive(gpiovals::Drive::H0H1); |
| 301 | #[cfg(feature = "_nrf54l")] | ||
| 302 | { | ||
| 303 | w.set_drive0(gpiovals::Drive::H); | ||
| 304 | w.set_drive1(gpiovals::Drive::H); | ||
| 305 | } | ||
| 300 | }); | 306 | }); |
| 301 | r.psel().txd().write_value(txd.psel_bits()); | 307 | r.psel().txd().write_value(txd.psel_bits()); |
| 302 | 308 | ||
| @@ -304,7 +310,13 @@ pub(crate) fn configure_tx_pins(r: pac::uarte::Uarte, txd: Peri<'_, AnyPin>, cts | |||
| 304 | pin.conf().write(|w| { | 310 | pin.conf().write(|w| { |
| 305 | w.set_dir(gpiovals::Dir::INPUT); | 311 | w.set_dir(gpiovals::Dir::INPUT); |
| 306 | w.set_input(gpiovals::Input::CONNECT); | 312 | w.set_input(gpiovals::Input::CONNECT); |
| 313 | #[cfg(not(feature = "_nrf54l"))] | ||
| 307 | w.set_drive(gpiovals::Drive::H0H1); | 314 | w.set_drive(gpiovals::Drive::H0H1); |
| 315 | #[cfg(feature = "_nrf54l")] | ||
| 316 | { | ||
| 317 | w.set_drive0(gpiovals::Drive::H); | ||
| 318 | w.set_drive1(gpiovals::Drive::H); | ||
| 319 | } | ||
| 308 | }); | 320 | }); |
| 309 | } | 321 | } |
| 310 | r.psel().cts().write_value(cts.psel_bits()); | 322 | r.psel().cts().write_value(cts.psel_bits()); |
| @@ -314,7 +326,13 @@ pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts | |||
| 314 | rxd.conf().write(|w| { | 326 | rxd.conf().write(|w| { |
| 315 | w.set_dir(gpiovals::Dir::INPUT); | 327 | w.set_dir(gpiovals::Dir::INPUT); |
| 316 | w.set_input(gpiovals::Input::CONNECT); | 328 | w.set_input(gpiovals::Input::CONNECT); |
| 329 | #[cfg(not(feature = "_nrf54l"))] | ||
| 317 | w.set_drive(gpiovals::Drive::H0H1); | 330 | w.set_drive(gpiovals::Drive::H0H1); |
| 331 | #[cfg(feature = "_nrf54l")] | ||
| 332 | { | ||
| 333 | w.set_drive0(gpiovals::Drive::H); | ||
| 334 | w.set_drive1(gpiovals::Drive::H); | ||
| 335 | } | ||
| 318 | }); | 336 | }); |
| 319 | r.psel().rxd().write_value(rxd.psel_bits()); | 337 | r.psel().rxd().write_value(rxd.psel_bits()); |
| 320 | 338 | ||
| @@ -323,7 +341,13 @@ pub(crate) fn configure_rx_pins(r: pac::uarte::Uarte, rxd: Peri<'_, AnyPin>, rts | |||
| 323 | pin.conf().write(|w| { | 341 | pin.conf().write(|w| { |
| 324 | w.set_dir(gpiovals::Dir::OUTPUT); | 342 | w.set_dir(gpiovals::Dir::OUTPUT); |
| 325 | w.set_input(gpiovals::Input::DISCONNECT); | 343 | w.set_input(gpiovals::Input::DISCONNECT); |
| 344 | #[cfg(not(feature = "_nrf54l"))] | ||
| 326 | w.set_drive(gpiovals::Drive::H0H1); | 345 | w.set_drive(gpiovals::Drive::H0H1); |
| 346 | #[cfg(feature = "_nrf54l")] | ||
| 347 | { | ||
| 348 | w.set_drive0(gpiovals::Drive::H); | ||
| 349 | w.set_drive1(gpiovals::Drive::H); | ||
| 350 | } | ||
| 327 | }); | 351 | }); |
| 328 | } | 352 | } |
| 329 | r.psel().rts().write_value(rts.psel_bits()); | 353 | r.psel().rts().write_value(rts.psel_bits()); |
| @@ -333,6 +357,10 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont | |||
| 333 | r.config().write(|w| { | 357 | r.config().write(|w| { |
| 334 | w.set_hwfc(hardware_flow_control); | 358 | w.set_hwfc(hardware_flow_control); |
| 335 | w.set_parity(config.parity); | 359 | w.set_parity(config.parity); |
| 360 | #[cfg(feature = "_nrf54l")] | ||
| 361 | w.set_framesize(vals::Framesize::_8BIT); | ||
| 362 | #[cfg(feature = "_nrf54l")] | ||
| 363 | w.set_frametimeout(true); | ||
| 336 | }); | 364 | }); |
| 337 | r.baudrate().write(|w| w.set_baudrate(config.baudrate)); | 365 | r.baudrate().write(|w| w.set_baudrate(config.baudrate)); |
| 338 | 366 | ||
| @@ -341,8 +369,8 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont | |||
| 341 | 369 | ||
| 342 | // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was | 370 | // Reset rxstarted, txstarted. These are used by drop to know whether a transfer was |
| 343 | // stopped midway or not. | 371 | // stopped midway or not. |
| 344 | r.events_rxstarted().write_value(0); | 372 | r.events_dma().rx().ready().write_value(0); |
| 345 | r.events_txstarted().write_value(0); | 373 | r.events_dma().tx().ready().write_value(0); |
| 346 | 374 | ||
| 347 | // reset all pins | 375 | // reset all pins |
| 348 | r.psel().txd().write_value(DISCONNECTED); | 376 | r.psel().txd().write_value(DISCONNECTED); |
| @@ -434,29 +462,29 @@ impl<'d> UarteTx<'d> { | |||
| 434 | let drop = OnDrop::new(move || { | 462 | let drop = OnDrop::new(move || { |
| 435 | trace!("write drop: stopping"); | 463 | trace!("write drop: stopping"); |
| 436 | 464 | ||
| 437 | r.intenclr().write(|w| w.set_endtx(true)); | 465 | r.intenclr().write(|w| w.set_dmatxend(true)); |
| 438 | r.events_txstopped().write_value(0); | 466 | r.events_txstopped().write_value(0); |
| 439 | r.tasks_stoptx().write_value(1); | 467 | r.tasks_dma().tx().stop().write_value(1); |
| 440 | 468 | ||
| 441 | // TX is stopped almost instantly, spinning is fine. | 469 | // TX is stopped almost instantly, spinning is fine. |
| 442 | while r.events_endtx().read() == 0 {} | 470 | while r.events_dma().tx().end().read() == 0 {} |
| 443 | trace!("write drop: stopped"); | 471 | trace!("write drop: stopped"); |
| 444 | }); | 472 | }); |
| 445 | 473 | ||
| 446 | r.txd().ptr().write_value(ptr as u32); | 474 | r.dma().tx().ptr().write_value(ptr as u32); |
| 447 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 475 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 448 | 476 | ||
| 449 | r.events_endtx().write_value(0); | 477 | r.events_dma().tx().end().write_value(0); |
| 450 | r.intenset().write(|w| w.set_endtx(true)); | 478 | r.intenset().write(|w| w.set_dmatxend(true)); |
| 451 | 479 | ||
| 452 | compiler_fence(Ordering::SeqCst); | 480 | compiler_fence(Ordering::SeqCst); |
| 453 | 481 | ||
| 454 | trace!("starttx"); | 482 | trace!("starttx"); |
| 455 | r.tasks_starttx().write_value(1); | 483 | r.tasks_dma().tx().start().write_value(1); |
| 456 | 484 | ||
| 457 | poll_fn(|cx| { | 485 | poll_fn(|cx| { |
| 458 | s.tx_waker.register(cx.waker()); | 486 | s.tx_waker.register(cx.waker()); |
| 459 | if r.events_endtx().read() != 0 { | 487 | if r.events_dma().tx().end().read() != 0 { |
| 460 | return Poll::Ready(()); | 488 | return Poll::Ready(()); |
| 461 | } | 489 | } |
| 462 | Poll::Pending | 490 | Poll::Pending |
| @@ -464,7 +492,7 @@ impl<'d> UarteTx<'d> { | |||
| 464 | .await; | 492 | .await; |
| 465 | 493 | ||
| 466 | compiler_fence(Ordering::SeqCst); | 494 | compiler_fence(Ordering::SeqCst); |
| 467 | r.events_txstarted().write_value(0); | 495 | r.events_dma().tx().ready().write_value(0); |
| 468 | drop.defuse(); | 496 | drop.defuse(); |
| 469 | 497 | ||
| 470 | Ok(()) | 498 | Ok(()) |
| @@ -500,21 +528,21 @@ impl<'d> UarteTx<'d> { | |||
| 500 | 528 | ||
| 501 | let r = self.r; | 529 | let r = self.r; |
| 502 | 530 | ||
| 503 | r.txd().ptr().write_value(ptr as u32); | 531 | r.dma().tx().ptr().write_value(ptr as u32); |
| 504 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 532 | r.dma().tx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 505 | 533 | ||
| 506 | r.events_endtx().write_value(0); | 534 | r.events_dma().tx().end().write_value(0); |
| 507 | r.intenclr().write(|w| w.set_endtx(true)); | 535 | r.intenclr().write(|w| w.set_dmatxend(true)); |
| 508 | 536 | ||
| 509 | compiler_fence(Ordering::SeqCst); | 537 | compiler_fence(Ordering::SeqCst); |
| 510 | 538 | ||
| 511 | trace!("starttx"); | 539 | trace!("starttx"); |
| 512 | r.tasks_starttx().write_value(1); | 540 | r.tasks_dma().tx().start().write_value(1); |
| 513 | 541 | ||
| 514 | while r.events_endtx().read() == 0 {} | 542 | while r.events_dma().tx().end().read() == 0 {} |
| 515 | 543 | ||
| 516 | compiler_fence(Ordering::SeqCst); | 544 | compiler_fence(Ordering::SeqCst); |
| 517 | r.events_txstarted().write_value(0); | 545 | r.events_dma().tx().ready().write_value(0); |
| 518 | 546 | ||
| 519 | Ok(()) | 547 | Ok(()) |
| 520 | } | 548 | } |
| @@ -526,7 +554,7 @@ impl<'a> Drop for UarteTx<'a> { | |||
| 526 | 554 | ||
| 527 | let r = self.r; | 555 | let r = self.r; |
| 528 | 556 | ||
| 529 | let did_stoptx = r.events_txstarted().read() != 0; | 557 | let did_stoptx = r.events_dma().tx().ready().read() != 0; |
| 530 | trace!("did_stoptx {}", did_stoptx); | 558 | trace!("did_stoptx {}", did_stoptx); |
| 531 | 559 | ||
| 532 | // Wait for txstopped, if needed. | 560 | // Wait for txstopped, if needed. |
| @@ -629,7 +657,7 @@ impl<'d> UarteRx<'d> { | |||
| 629 | let mut ppi_ch2 = Ppi::new_one_to_one( | 657 | let mut ppi_ch2 = Ppi::new_one_to_one( |
| 630 | ppi_ch2.into(), | 658 | ppi_ch2.into(), |
| 631 | timer.cc(0).event_compare(), | 659 | timer.cc(0).event_compare(), |
| 632 | Task::from_reg(r.tasks_stoprx()), | 660 | Task::from_reg(r.tasks_dma().rx().stop()), |
| 633 | ); | 661 | ); |
| 634 | ppi_ch2.enable(); | 662 | ppi_ch2.enable(); |
| 635 | 663 | ||
| @@ -664,41 +692,41 @@ impl<'d> UarteRx<'d> { | |||
| 664 | trace!("read drop: stopping"); | 692 | trace!("read drop: stopping"); |
| 665 | 693 | ||
| 666 | r.intenclr().write(|w| { | 694 | r.intenclr().write(|w| { |
| 667 | w.set_endrx(true); | 695 | w.set_dmarxend(true); |
| 668 | w.set_error(true); | 696 | w.set_error(true); |
| 669 | }); | 697 | }); |
| 670 | r.events_rxto().write_value(0); | 698 | r.events_rxto().write_value(0); |
| 671 | r.events_error().write_value(0); | 699 | r.events_error().write_value(0); |
| 672 | r.tasks_stoprx().write_value(1); | 700 | r.tasks_dma().rx().stop().write_value(1); |
| 673 | 701 | ||
| 674 | while r.events_endrx().read() == 0 {} | 702 | while r.events_dma().rx().end().read() == 0 {} |
| 675 | 703 | ||
| 676 | trace!("read drop: stopped"); | 704 | trace!("read drop: stopped"); |
| 677 | }); | 705 | }); |
| 678 | 706 | ||
| 679 | r.rxd().ptr().write_value(ptr as u32); | 707 | r.dma().rx().ptr().write_value(ptr as u32); |
| 680 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 708 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 681 | 709 | ||
| 682 | r.events_endrx().write_value(0); | 710 | r.events_dma().rx().end().write_value(0); |
| 683 | r.events_error().write_value(0); | 711 | r.events_error().write_value(0); |
| 684 | r.intenset().write(|w| { | 712 | r.intenset().write(|w| { |
| 685 | w.set_endrx(true); | 713 | w.set_dmarxend(true); |
| 686 | w.set_error(true); | 714 | w.set_error(true); |
| 687 | }); | 715 | }); |
| 688 | 716 | ||
| 689 | compiler_fence(Ordering::SeqCst); | 717 | compiler_fence(Ordering::SeqCst); |
| 690 | 718 | ||
| 691 | trace!("startrx"); | 719 | trace!("startrx"); |
| 692 | r.tasks_startrx().write_value(1); | 720 | r.tasks_dma().rx().start().write_value(1); |
| 693 | 721 | ||
| 694 | let result = poll_fn(|cx| { | 722 | let result = poll_fn(|cx| { |
| 695 | s.rx_waker.register(cx.waker()); | 723 | s.rx_waker.register(cx.waker()); |
| 696 | 724 | ||
| 697 | if let Err(e) = self.check_and_clear_errors() { | 725 | if let Err(e) = self.check_and_clear_errors() { |
| 698 | r.tasks_stoprx().write_value(1); | 726 | r.tasks_dma().rx().stop().write_value(1); |
| 699 | return Poll::Ready(Err(e)); | 727 | return Poll::Ready(Err(e)); |
| 700 | } | 728 | } |
| 701 | if r.events_endrx().read() != 0 { | 729 | if r.events_dma().rx().end().read() != 0 { |
| 702 | return Poll::Ready(Ok(())); | 730 | return Poll::Ready(Ok(())); |
| 703 | } | 731 | } |
| 704 | Poll::Pending | 732 | Poll::Pending |
| @@ -706,7 +734,7 @@ impl<'d> UarteRx<'d> { | |||
| 706 | .await; | 734 | .await; |
| 707 | 735 | ||
| 708 | compiler_fence(Ordering::SeqCst); | 736 | compiler_fence(Ordering::SeqCst); |
| 709 | r.events_rxstarted().write_value(0); | 737 | r.events_dma().rx().ready().write_value(0); |
| 710 | drop.defuse(); | 738 | drop.defuse(); |
| 711 | 739 | ||
| 712 | result | 740 | result |
| @@ -726,25 +754,25 @@ impl<'d> UarteRx<'d> { | |||
| 726 | 754 | ||
| 727 | let r = self.r; | 755 | let r = self.r; |
| 728 | 756 | ||
| 729 | r.rxd().ptr().write_value(ptr as u32); | 757 | r.dma().rx().ptr().write_value(ptr as u32); |
| 730 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 758 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 731 | 759 | ||
| 732 | r.events_endrx().write_value(0); | 760 | r.events_dma().rx().end().write_value(0); |
| 733 | r.events_error().write_value(0); | 761 | r.events_error().write_value(0); |
| 734 | r.intenclr().write(|w| { | 762 | r.intenclr().write(|w| { |
| 735 | w.set_endrx(true); | 763 | w.set_dmarxend(true); |
| 736 | w.set_error(true); | 764 | w.set_error(true); |
| 737 | }); | 765 | }); |
| 738 | 766 | ||
| 739 | compiler_fence(Ordering::SeqCst); | 767 | compiler_fence(Ordering::SeqCst); |
| 740 | 768 | ||
| 741 | trace!("startrx"); | 769 | trace!("startrx"); |
| 742 | r.tasks_startrx().write_value(1); | 770 | r.tasks_dma().rx().start().write_value(1); |
| 743 | 771 | ||
| 744 | while r.events_endrx().read() == 0 && r.events_error().read() == 0 {} | 772 | while r.events_dma().rx().end().read() == 0 && r.events_error().read() == 0 {} |
| 745 | 773 | ||
| 746 | compiler_fence(Ordering::SeqCst); | 774 | compiler_fence(Ordering::SeqCst); |
| 747 | r.events_rxstarted().write_value(0); | 775 | r.events_dma().rx().ready().write_value(0); |
| 748 | 776 | ||
| 749 | self.check_and_clear_errors() | 777 | self.check_and_clear_errors() |
| 750 | } | 778 | } |
| @@ -756,7 +784,7 @@ impl<'a> Drop for UarteRx<'a> { | |||
| 756 | 784 | ||
| 757 | let r = self.r; | 785 | let r = self.r; |
| 758 | 786 | ||
| 759 | let did_stoprx = r.events_rxstarted().read() != 0; | 787 | let did_stoprx = r.events_dma().rx().ready().read() != 0; |
| 760 | trace!("did_stoprx {}", did_stoprx); | 788 | trace!("did_stoprx {}", did_stoprx); |
| 761 | 789 | ||
| 762 | // Wait for rxto, if needed. | 790 | // Wait for rxto, if needed. |
| @@ -816,38 +844,38 @@ impl<'d> UarteRxWithIdle<'d> { | |||
| 816 | self.timer.stop(); | 844 | self.timer.stop(); |
| 817 | 845 | ||
| 818 | r.intenclr().write(|w| { | 846 | r.intenclr().write(|w| { |
| 819 | w.set_endrx(true); | 847 | w.set_dmarxend(true); |
| 820 | w.set_error(true); | 848 | w.set_error(true); |
| 821 | }); | 849 | }); |
| 822 | r.events_rxto().write_value(0); | 850 | r.events_rxto().write_value(0); |
| 823 | r.events_error().write_value(0); | 851 | r.events_error().write_value(0); |
| 824 | r.tasks_stoprx().write_value(1); | 852 | r.tasks_dma().rx().stop().write_value(1); |
| 825 | 853 | ||
| 826 | while r.events_endrx().read() == 0 {} | 854 | while r.events_dma().rx().end().read() == 0 {} |
| 827 | }); | 855 | }); |
| 828 | 856 | ||
| 829 | r.rxd().ptr().write_value(ptr as u32); | 857 | r.dma().rx().ptr().write_value(ptr as u32); |
| 830 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 858 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 831 | 859 | ||
| 832 | r.events_endrx().write_value(0); | 860 | r.events_dma().rx().end().write_value(0); |
| 833 | r.events_error().write_value(0); | 861 | r.events_error().write_value(0); |
| 834 | r.intenset().write(|w| { | 862 | r.intenset().write(|w| { |
| 835 | w.set_endrx(true); | 863 | w.set_dmarxend(true); |
| 836 | w.set_error(true); | 864 | w.set_error(true); |
| 837 | }); | 865 | }); |
| 838 | 866 | ||
| 839 | compiler_fence(Ordering::SeqCst); | 867 | compiler_fence(Ordering::SeqCst); |
| 840 | 868 | ||
| 841 | r.tasks_startrx().write_value(1); | 869 | r.tasks_dma().rx().start().write_value(1); |
| 842 | 870 | ||
| 843 | let result = poll_fn(|cx| { | 871 | let result = poll_fn(|cx| { |
| 844 | s.rx_waker.register(cx.waker()); | 872 | s.rx_waker.register(cx.waker()); |
| 845 | 873 | ||
| 846 | if let Err(e) = self.rx.check_and_clear_errors() { | 874 | if let Err(e) = self.rx.check_and_clear_errors() { |
| 847 | r.tasks_stoprx().write_value(1); | 875 | r.tasks_dma().rx().stop().write_value(1); |
| 848 | return Poll::Ready(Err(e)); | 876 | return Poll::Ready(Err(e)); |
| 849 | } | 877 | } |
| 850 | if r.events_endrx().read() != 0 { | 878 | if r.events_dma().rx().end().read() != 0 { |
| 851 | return Poll::Ready(Ok(())); | 879 | return Poll::Ready(Ok(())); |
| 852 | } | 880 | } |
| 853 | 881 | ||
| @@ -856,10 +884,10 @@ impl<'d> UarteRxWithIdle<'d> { | |||
| 856 | .await; | 884 | .await; |
| 857 | 885 | ||
| 858 | compiler_fence(Ordering::SeqCst); | 886 | compiler_fence(Ordering::SeqCst); |
| 859 | let n = r.rxd().amount().read().0 as usize; | 887 | let n = r.dma().rx().amount().read().0 as usize; |
| 860 | 888 | ||
| 861 | self.timer.stop(); | 889 | self.timer.stop(); |
| 862 | r.events_rxstarted().write_value(0); | 890 | r.events_dma().rx().ready().write_value(0); |
| 863 | 891 | ||
| 864 | drop.defuse(); | 892 | drop.defuse(); |
| 865 | 893 | ||
| @@ -884,27 +912,27 @@ impl<'d> UarteRxWithIdle<'d> { | |||
| 884 | 912 | ||
| 885 | self.ppi_ch1.enable(); | 913 | self.ppi_ch1.enable(); |
| 886 | 914 | ||
| 887 | r.rxd().ptr().write_value(ptr as u32); | 915 | r.dma().rx().ptr().write_value(ptr as u32); |
| 888 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 916 | r.dma().rx().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| 889 | 917 | ||
| 890 | r.events_endrx().write_value(0); | 918 | r.events_dma().rx().end().write_value(0); |
| 891 | r.events_error().write_value(0); | 919 | r.events_error().write_value(0); |
| 892 | r.intenclr().write(|w| { | 920 | r.intenclr().write(|w| { |
| 893 | w.set_endrx(true); | 921 | w.set_dmarxend(true); |
| 894 | w.set_error(true); | 922 | w.set_error(true); |
| 895 | }); | 923 | }); |
| 896 | 924 | ||
| 897 | compiler_fence(Ordering::SeqCst); | 925 | compiler_fence(Ordering::SeqCst); |
| 898 | 926 | ||
| 899 | r.tasks_startrx().write_value(1); | 927 | r.tasks_dma().rx().start().write_value(1); |
| 900 | 928 | ||
| 901 | while r.events_endrx().read() == 0 && r.events_error().read() == 0 {} | 929 | while r.events_dma().rx().end().read() == 0 && r.events_error().read() == 0 {} |
| 902 | 930 | ||
| 903 | compiler_fence(Ordering::SeqCst); | 931 | compiler_fence(Ordering::SeqCst); |
| 904 | let n = r.rxd().amount().read().0 as usize; | 932 | let n = r.dma().rx().amount().read().0 as usize; |
| 905 | 933 | ||
| 906 | self.timer.stop(); | 934 | self.timer.stop(); |
| 907 | r.events_rxstarted().write_value(0); | 935 | r.events_dma().rx().ready().write_value(0); |
| 908 | 936 | ||
| 909 | self.rx.check_and_clear_errors().map(|_| n) | 937 | self.rx.check_and_clear_errors().map(|_| n) |
| 910 | } | 938 | } |
| @@ -927,14 +955,14 @@ pub(crate) fn apply_workaround_for_enable_anomaly(r: pac::uarte::Uarte) { | |||
| 927 | // NB Safety: This is taken from Nordic's driver - | 955 | // NB Safety: This is taken from Nordic's driver - |
| 928 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | 956 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 |
| 929 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { | 957 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { |
| 930 | r.tasks_stoptx().write_value(1); | 958 | r.tasks_dma().tx().stop().write_value(1); |
| 931 | } | 959 | } |
| 932 | 960 | ||
| 933 | // NB Safety: This is taken from Nordic's driver - | 961 | // NB Safety: This is taken from Nordic's driver - |
| 934 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | 962 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 |
| 935 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { | 963 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { |
| 936 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 964 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 937 | r.tasks_stoprx().write_value(1); | 965 | r.tasks_dma().rx().stop().write_value(1); |
| 938 | 966 | ||
| 939 | let mut workaround_succeded = false; | 967 | let mut workaround_succeded = false; |
| 940 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. | 968 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. |
diff --git a/examples/nrf52840/src/bin/egu.rs b/examples/nrf52840/src/bin/egu.rs index 8bf712697..36eba8084 100644 --- a/examples/nrf52840/src/bin/egu.rs +++ b/examples/nrf52840/src/bin/egu.rs | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::egu::{Egu, TriggerNumber}; | 8 | use embassy_nrf::egu::{Egu, TriggerNumber}; |
| 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 9 | use embassy_nrf::gpio::{Level, OutputDrive, Pull}; |
| 10 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity}; | 10 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity}; |
| 11 | use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2}; | 11 | use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2}; |
| 12 | use embassy_nrf::ppi::Ppi; | 12 | use embassy_nrf::ppi::Ppi; |
| @@ -17,12 +17,15 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 17 | async fn main(_spawner: Spawner) { | 17 | async fn main(_spawner: Spawner) { |
| 18 | let p = embassy_nrf::init(Default::default()); | 18 | let p = embassy_nrf::init(Default::default()); |
| 19 | 19 | ||
| 20 | let led1 = Output::new(p.P0_13, Level::High, OutputDrive::Standard); | ||
| 21 | let btn1 = Input::new(p.P0_11, Pull::Up); | ||
| 22 | |||
| 23 | let mut egu1 = Egu::new(p.EGU0); | 20 | let mut egu1 = Egu::new(p.EGU0); |
| 24 | let led1 = OutputChannel::new(p.GPIOTE_CH0, led1, OutputChannelPolarity::Toggle); | 21 | let led1 = OutputChannel::new( |
| 25 | let btn1 = InputChannel::new(p.GPIOTE_CH1, btn1, InputChannelPolarity::LoToHi); | 22 | p.GPIOTE_CH0, |
| 23 | p.P0_13, | ||
| 24 | Level::High, | ||
| 25 | OutputDrive::Standard, | ||
| 26 | OutputChannelPolarity::Toggle, | ||
| 27 | ); | ||
| 28 | let btn1 = InputChannel::new(p.GPIOTE_CH1, p.P0_11, Pull::Up, InputChannelPolarity::LoToHi); | ||
| 26 | 29 | ||
| 27 | let trigger0 = egu1.trigger(TriggerNumber::Trigger0); | 30 | let trigger0 = egu1.trigger(TriggerNumber::Trigger0); |
| 28 | let trigger1 = egu1.trigger(TriggerNumber::Trigger1); | 31 | let trigger1 = egu1.trigger(TriggerNumber::Trigger1); |
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs index dcfe7723a..c7ddc1d8d 100644 --- a/examples/nrf52840/src/bin/gpiote_channel.rs +++ b/examples/nrf52840/src/bin/gpiote_channel.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{Input, Pull}; | 6 | use embassy_nrf::gpio::Pull; |
| 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -12,26 +12,10 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_nrf::init(Default::default()); | 12 | let p = embassy_nrf::init(Default::default()); |
| 13 | info!("Starting!"); | 13 | info!("Starting!"); |
| 14 | 14 | ||
| 15 | let ch1 = InputChannel::new( | 15 | let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); |
| 16 | p.GPIOTE_CH0, | 16 | let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi); |
| 17 | Input::new(p.P0_11, Pull::Up), | 17 | let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle); |
| 18 | InputChannelPolarity::HiToLo, | 18 | let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle); |
| 19 | ); | ||
| 20 | let ch2 = InputChannel::new( | ||
| 21 | p.GPIOTE_CH1, | ||
| 22 | Input::new(p.P0_12, Pull::Up), | ||
| 23 | InputChannelPolarity::LoToHi, | ||
| 24 | ); | ||
| 25 | let ch3 = InputChannel::new( | ||
| 26 | p.GPIOTE_CH2, | ||
| 27 | Input::new(p.P0_24, Pull::Up), | ||
| 28 | InputChannelPolarity::Toggle, | ||
| 29 | ); | ||
| 30 | let ch4 = InputChannel::new( | ||
| 31 | p.GPIOTE_CH3, | ||
| 32 | Input::new(p.P0_25, Pull::Up), | ||
| 33 | InputChannelPolarity::Toggle, | ||
| 34 | ); | ||
| 35 | 19 | ||
| 36 | let button1 = async { | 20 | let button1 = async { |
| 37 | loop { | 21 | loop { |
diff --git a/examples/nrf52840/src/bin/ppi.rs b/examples/nrf52840/src/bin/ppi.rs index 129ad06e7..177f6a06d 100644 --- a/examples/nrf52840/src/bin/ppi.rs +++ b/examples/nrf52840/src/bin/ppi.rs | |||
| @@ -5,7 +5,7 @@ use core::future::pending; | |||
| 5 | 5 | ||
| 6 | use defmt::info; | 6 | use defmt::info; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | 8 | use embassy_nrf::gpio::{Level, OutputDrive, Pull}; |
| 9 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; | 9 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; |
| 10 | use embassy_nrf::ppi::Ppi; | 10 | use embassy_nrf::ppi::Ppi; |
| 11 | use gpiote::{OutputChannel, OutputChannelPolarity}; | 11 | use gpiote::{OutputChannel, OutputChannelPolarity}; |
| @@ -16,36 +16,24 @@ async fn main(_spawner: Spawner) { | |||
| 16 | let p = embassy_nrf::init(Default::default()); | 16 | let p = embassy_nrf::init(Default::default()); |
| 17 | info!("Starting!"); | 17 | info!("Starting!"); |
| 18 | 18 | ||
| 19 | let button1 = InputChannel::new( | 19 | let button1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); |
| 20 | p.GPIOTE_CH0, | 20 | let button2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::HiToLo); |
| 21 | Input::new(p.P0_11, Pull::Up), | 21 | let button3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::HiToLo); |
| 22 | InputChannelPolarity::HiToLo, | 22 | let button4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::HiToLo); |
| 23 | ); | ||
| 24 | let button2 = InputChannel::new( | ||
| 25 | p.GPIOTE_CH1, | ||
| 26 | Input::new(p.P0_12, Pull::Up), | ||
| 27 | InputChannelPolarity::HiToLo, | ||
| 28 | ); | ||
| 29 | let button3 = InputChannel::new( | ||
| 30 | p.GPIOTE_CH2, | ||
| 31 | Input::new(p.P0_24, Pull::Up), | ||
| 32 | InputChannelPolarity::HiToLo, | ||
| 33 | ); | ||
| 34 | let button4 = InputChannel::new( | ||
| 35 | p.GPIOTE_CH3, | ||
| 36 | Input::new(p.P0_25, Pull::Up), | ||
| 37 | InputChannelPolarity::HiToLo, | ||
| 38 | ); | ||
| 39 | 23 | ||
| 40 | let led1 = OutputChannel::new( | 24 | let led1 = OutputChannel::new( |
| 41 | p.GPIOTE_CH4, | 25 | p.GPIOTE_CH4, |
| 42 | Output::new(p.P0_13, Level::Low, OutputDrive::Standard), | 26 | p.P0_13, |
| 27 | Level::Low, | ||
| 28 | OutputDrive::Standard, | ||
| 43 | OutputChannelPolarity::Toggle, | 29 | OutputChannelPolarity::Toggle, |
| 44 | ); | 30 | ); |
| 45 | 31 | ||
| 46 | let led2 = OutputChannel::new( | 32 | let led2 = OutputChannel::new( |
| 47 | p.GPIOTE_CH5, | 33 | p.GPIOTE_CH5, |
| 48 | Output::new(p.P0_14, Level::Low, OutputDrive::Standard), | 34 | p.P0_14, |
| 35 | Level::Low, | ||
| 36 | OutputDrive::Standard, | ||
| 49 | OutputChannelPolarity::Toggle, | 37 | OutputChannelPolarity::Toggle, |
| 50 | ); | 38 | ); |
| 51 | 39 | ||
diff --git a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs index 60ea712b5..fff7decb2 100644 --- a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs +++ b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs | |||
| @@ -5,7 +5,7 @@ use core::future::pending; | |||
| 5 | 5 | ||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::gpio::{Input, Pull}; | 8 | use embassy_nrf::gpio::Pull; |
| 9 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | 9 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 10 | use embassy_nrf::ppi::Ppi; | 10 | use embassy_nrf::ppi::Ppi; |
| 11 | use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; | 11 | use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; |
| @@ -30,17 +30,9 @@ async fn main(_spawner: Spawner) { | |||
| 30 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work | 30 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work |
| 31 | // so its going to have to start running in order load the configuration | 31 | // so its going to have to start running in order load the configuration |
| 32 | 32 | ||
| 33 | let button1 = InputChannel::new( | 33 | let button1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); |
| 34 | p.GPIOTE_CH0, | ||
| 35 | Input::new(p.P0_11, Pull::Up), | ||
| 36 | InputChannelPolarity::HiToLo, | ||
| 37 | ); | ||
| 38 | 34 | ||
| 39 | let button2 = InputChannel::new( | 35 | let button2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::HiToLo); |
| 40 | p.GPIOTE_CH1, | ||
| 41 | Input::new(p.P0_12, Pull::Up), | ||
| 42 | InputChannelPolarity::HiToLo, | ||
| 43 | ); | ||
| 44 | 36 | ||
| 45 | // messing with the pwm tasks is ill advised | 37 | // messing with the pwm tasks is ill advised |
| 46 | // Times::Ininite and Times even are seq0, Times odd is seq1 | 38 | // Times::Ininite and Times even are seq0, Times odd is seq1 |
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs index 23f6fca98..a085310ce 100644 --- a/examples/nrf5340/src/bin/gpiote_channel.rs +++ b/examples/nrf5340/src/bin/gpiote_channel.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::gpio::{Input, Pull}; | 6 | use embassy_nrf::gpio::Pull; |
| 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 8 | use {defmt_rtt as _, panic_probe as _}; | 8 | use {defmt_rtt as _, panic_probe as _}; |
| 9 | 9 | ||
| @@ -12,26 +12,10 @@ async fn main(_spawner: Spawner) { | |||
| 12 | let p = embassy_nrf::init(Default::default()); | 12 | let p = embassy_nrf::init(Default::default()); |
| 13 | info!("Starting!"); | 13 | info!("Starting!"); |
| 14 | 14 | ||
| 15 | let ch1 = InputChannel::new( | 15 | let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo); |
| 16 | p.GPIOTE_CH0, | 16 | let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi); |
| 17 | Input::new(p.P0_23, Pull::Up), | 17 | let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle); |
| 18 | InputChannelPolarity::HiToLo, | 18 | let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle); |
| 19 | ); | ||
| 20 | let ch2 = InputChannel::new( | ||
| 21 | p.GPIOTE_CH1, | ||
| 22 | Input::new(p.P0_24, Pull::Up), | ||
| 23 | InputChannelPolarity::LoToHi, | ||
| 24 | ); | ||
| 25 | let ch3 = InputChannel::new( | ||
| 26 | p.GPIOTE_CH2, | ||
| 27 | Input::new(p.P0_08, Pull::Up), | ||
| 28 | InputChannelPolarity::Toggle, | ||
| 29 | ); | ||
| 30 | let ch4 = InputChannel::new( | ||
| 31 | p.GPIOTE_CH3, | ||
| 32 | Input::new(p.P0_09, Pull::Up), | ||
| 33 | InputChannelPolarity::Toggle, | ||
| 34 | ); | ||
| 35 | 19 | ||
| 36 | let button1 = async { | 20 | let button1 = async { |
| 37 | loop { | 21 | loop { |
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml index 541e79fcb..14a80efe7 100644 --- a/examples/nrf54l15/Cargo.toml +++ b/examples/nrf54l15/Cargo.toml | |||
| @@ -6,10 +6,13 @@ license = "MIT OR Apache-2.0" | |||
| 6 | publish = false | 6 | publish = false |
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | ||
| 9 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 10 | embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 10 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 11 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } | 12 | embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] } |
| 12 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 13 | embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 14 | embedded-io = { version = "0.6.0", features = ["defmt-03"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 13 | 16 | ||
| 14 | defmt = "1.0.1" | 17 | defmt = "1.0.1" |
| 15 | defmt-rtt = "1.0.0" | 18 | defmt-rtt = "1.0.0" |
| @@ -21,6 +24,8 @@ cortex-m-rt = "0.7.0" | |||
| 21 | embedded-storage = "0.3.1" | 24 | embedded-storage = "0.3.1" |
| 22 | portable-atomic = "1" | 25 | portable-atomic = "1" |
| 23 | 26 | ||
| 27 | static_cell = "2" | ||
| 28 | |||
| 24 | [profile.release] | 29 | [profile.release] |
| 25 | debug = 2 | 30 | debug = 2 |
| 26 | 31 | ||
diff --git a/examples/nrf54l15/src/bin/buffered_uart.rs b/examples/nrf54l15/src/bin/buffered_uart.rs new file mode 100644 index 000000000..41fa1ca4e --- /dev/null +++ b/examples/nrf54l15/src/bin/buffered_uart.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | ||
| 7 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 8 | use embedded_io_async::Write; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | SERIAL20 => buffered_uarte::InterruptHandler<peripherals::SERIAL20>; | ||
| 13 | }); | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD115200; | ||
| 21 | |||
| 22 | let mut tx_buffer = [0u8; 4096]; | ||
| 23 | let mut rx_buffer = [0u8; 4096]; | ||
| 24 | |||
| 25 | let mut u = BufferedUarte::new( | ||
| 26 | p.SERIAL20, | ||
| 27 | p.P1_12, | ||
| 28 | p.P1_13, | ||
| 29 | Irqs, | ||
| 30 | config, | ||
| 31 | &mut rx_buffer, | ||
| 32 | &mut tx_buffer, | ||
| 33 | ); | ||
| 34 | |||
| 35 | info!("uarte initialized!"); | ||
| 36 | |||
| 37 | unwrap!(u.write_all(b"Hello!\r\n").await); | ||
| 38 | info!("wrote hello in uart!"); | ||
| 39 | |||
| 40 | loop { | ||
| 41 | info!("reading..."); | ||
| 42 | let buf = unwrap!(u.fill_buf().await); | ||
| 43 | info!("read done, got {}", buf); | ||
| 44 | |||
| 45 | // Read bytes have to be explicitly consumed, otherwise fill_buf() will return them again | ||
| 46 | let n = buf.len(); | ||
| 47 | u.consume(n); | ||
| 48 | } | ||
| 49 | } | ||
diff --git a/examples/nrf54l15/src/bin/gpiote_channel.rs b/examples/nrf54l15/src/bin/gpiote_channel.rs new file mode 100644 index 000000000..6333250ba --- /dev/null +++ b/examples/nrf54l15/src/bin/gpiote_channel.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::info; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::gpio::Pull; | ||
| 7 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let p = embassy_nrf::init(Default::default()); | ||
| 13 | info!("Starting!"); | ||
| 14 | |||
| 15 | let ch1 = InputChannel::new(p.GPIOTE20_CH0, p.P1_13, Pull::Up, InputChannelPolarity::HiToLo); | ||
| 16 | let ch2 = InputChannel::new(p.GPIOTE20_CH1, p.P1_09, Pull::Up, InputChannelPolarity::LoToHi); | ||
| 17 | let ch3 = InputChannel::new(p.GPIOTE20_CH2, p.P1_08, Pull::Up, InputChannelPolarity::Toggle); | ||
| 18 | let ch4 = InputChannel::new(p.GPIOTE30_CH0, p.P0_04, Pull::Up, InputChannelPolarity::Toggle); | ||
| 19 | |||
| 20 | let button1 = async { | ||
| 21 | loop { | ||
| 22 | ch1.wait().await; | ||
| 23 | info!("Button 1 pressed") | ||
| 24 | } | ||
| 25 | }; | ||
| 26 | |||
| 27 | let button2 = async { | ||
| 28 | loop { | ||
| 29 | ch2.wait().await; | ||
| 30 | info!("Button 2 released") | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 34 | let button3 = async { | ||
| 35 | loop { | ||
| 36 | ch3.wait().await; | ||
| 37 | info!("Button 3 toggled") | ||
| 38 | } | ||
| 39 | }; | ||
| 40 | |||
| 41 | let button4 = async { | ||
| 42 | loop { | ||
| 43 | ch4.wait().await; | ||
| 44 | info!("Button 4 toggled") | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | |||
| 48 | embassy_futures::join::join4(button1, button2, button3, button4).await; | ||
| 49 | } | ||
diff --git a/examples/nrf54l15/src/bin/gpiote_port.rs b/examples/nrf54l15/src/bin/gpiote_port.rs new file mode 100644 index 000000000..620cb2435 --- /dev/null +++ b/examples/nrf54l15/src/bin/gpiote_port.rs | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{info, unwrap}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::gpio::{Input, Pull}; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | #[embassy_executor::task(pool_size = 4)] | ||
| 10 | async fn button_task(n: usize, mut pin: Input<'static>) { | ||
| 11 | loop { | ||
| 12 | pin.wait_for_low().await; | ||
| 13 | info!("Button {:?} pressed!", n); | ||
| 14 | pin.wait_for_high().await; | ||
| 15 | info!("Button {:?} released!", n); | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(spawner: Spawner) { | ||
| 21 | let p = embassy_nrf::init(Default::default()); | ||
| 22 | info!("Starting!"); | ||
| 23 | |||
| 24 | let btn1 = Input::new(p.P1_13, Pull::Up); | ||
| 25 | let btn2 = Input::new(p.P1_09, Pull::Up); | ||
| 26 | let btn3 = Input::new(p.P1_08, Pull::Up); | ||
| 27 | let btn4 = Input::new(p.P0_04, Pull::Up); | ||
| 28 | |||
| 29 | spawner.spawn(unwrap!(button_task(1, btn1))); | ||
| 30 | spawner.spawn(unwrap!(button_task(2, btn2))); | ||
| 31 | spawner.spawn(unwrap!(button_task(3, btn3))); | ||
| 32 | spawner.spawn(unwrap!(button_task(4, btn4))); | ||
| 33 | } | ||
diff --git a/examples/nrf54l15/src/bin/pwm.rs b/examples/nrf54l15/src/bin/pwm.rs new file mode 100644 index 000000000..b438978f1 --- /dev/null +++ b/examples/nrf54l15/src/bin/pwm.rs | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm}; | ||
| 7 | use embassy_time::Timer; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | // for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='') | ||
| 11 | static DUTY: [u16; 1024] = [ | ||
| 12 | 8191, 8272, 8353, 8434, 8516, 8598, 8681, 8764, 8847, 8931, 9015, 9099, 9184, 9269, 9354, 9440, 9526, 9613, 9700, | ||
| 13 | 9787, 9874, 9962, 10050, 10139, 10227, 10316, 10406, 10495, 10585, 10675, 10766, 10857, 10948, 11039, 11131, 11223, | ||
| 14 | 11315, 11407, 11500, 11592, 11685, 11779, 11872, 11966, 12060, 12154, 12248, 12343, 12438, 12533, 12628, 12723, | ||
| 15 | 12818, 12914, 13010, 13106, 13202, 13298, 13394, 13491, 13587, 13684, 13781, 13878, 13975, 14072, 14169, 14266, | ||
| 16 | 14364, 14461, 14558, 14656, 14754, 14851, 14949, 15046, 15144, 15242, 15339, 15437, 15535, 15632, 15730, 15828, | ||
| 17 | 15925, 16023, 16120, 16218, 16315, 16412, 16510, 16607, 16704, 16801, 16898, 16995, 17091, 17188, 17284, 17380, | ||
| 18 | 17477, 17572, 17668, 17764, 17859, 17955, 18050, 18145, 18239, 18334, 18428, 18522, 18616, 18710, 18803, 18896, | ||
| 19 | 18989, 19082, 19174, 19266, 19358, 19449, 19540, 19631, 19722, 19812, 19902, 19991, 20081, 20169, 20258, 20346, | ||
| 20 | 20434, 20521, 20608, 20695, 20781, 20867, 20952, 21037, 21122, 21206, 21290, 21373, 21456, 21538, 21620, 21701, | ||
| 21 | 21782, 21863, 21943, 22022, 22101, 22179, 22257, 22335, 22412, 22488, 22564, 22639, 22714, 22788, 22861, 22934, | ||
| 22 | 23007, 23079, 23150, 23220, 23290, 23360, 23429, 23497, 23564, 23631, 23698, 23763, 23828, 23892, 23956, 24019, | ||
| 23 | 24081, 24143, 24204, 24264, 24324, 24383, 24441, 24499, 24555, 24611, 24667, 24721, 24775, 24828, 24881, 24933, | ||
| 24 | 24983, 25034, 25083, 25132, 25180, 25227, 25273, 25319, 25363, 25407, 25451, 25493, 25535, 25575, 25615, 25655, | ||
| 25 | 25693, 25731, 25767, 25803, 25838, 25873, 25906, 25939, 25971, 26002, 26032, 26061, 26089, 26117, 26144, 26170, | ||
| 26 | 26195, 26219, 26242, 26264, 26286, 26307, 26327, 26346, 26364, 26381, 26397, 26413, 26427, 26441, 26454, 26466, | ||
| 27 | 26477, 26487, 26496, 26505, 26512, 26519, 26525, 26530, 26534, 26537, 26539, 26540, 26541, 26540, 26539, 26537, | ||
| 28 | 26534, 26530, 26525, 26519, 26512, 26505, 26496, 26487, 26477, 26466, 26454, 26441, 26427, 26413, 26397, 26381, | ||
| 29 | 26364, 26346, 26327, 26307, 26286, 26264, 26242, 26219, 26195, 26170, 26144, 26117, 26089, 26061, 26032, 26002, | ||
| 30 | 25971, 25939, 25906, 25873, 25838, 25803, 25767, 25731, 25693, 25655, 25615, 25575, 25535, 25493, 25451, 25407, | ||
| 31 | 25363, 25319, 25273, 25227, 25180, 25132, 25083, 25034, 24983, 24933, 24881, 24828, 24775, 24721, 24667, 24611, | ||
| 32 | 24555, 24499, 24441, 24383, 24324, 24264, 24204, 24143, 24081, 24019, 23956, 23892, 23828, 23763, 23698, 23631, | ||
| 33 | 23564, 23497, 23429, 23360, 23290, 23220, 23150, 23079, 23007, 22934, 22861, 22788, 22714, 22639, 22564, 22488, | ||
| 34 | 22412, 22335, 22257, 22179, 22101, 22022, 21943, 21863, 21782, 21701, 21620, 21538, 21456, 21373, 21290, 21206, | ||
| 35 | 21122, 21037, 20952, 20867, 20781, 20695, 20608, 20521, 20434, 20346, 20258, 20169, 20081, 19991, 19902, 19812, | ||
| 36 | 19722, 19631, 19540, 19449, 19358, 19266, 19174, 19082, 18989, 18896, 18803, 18710, 18616, 18522, 18428, 18334, | ||
| 37 | 18239, 18145, 18050, 17955, 17859, 17764, 17668, 17572, 17477, 17380, 17284, 17188, 17091, 16995, 16898, 16801, | ||
| 38 | 16704, 16607, 16510, 16412, 16315, 16218, 16120, 16023, 15925, 15828, 15730, 15632, 15535, 15437, 15339, 15242, | ||
| 39 | 15144, 15046, 14949, 14851, 14754, 14656, 14558, 14461, 14364, 14266, 14169, 14072, 13975, 13878, 13781, 13684, | ||
| 40 | 13587, 13491, 13394, 13298, 13202, 13106, 13010, 12914, 12818, 12723, 12628, 12533, 12438, 12343, 12248, 12154, | ||
| 41 | 12060, 11966, 11872, 11779, 11685, 11592, 11500, 11407, 11315, 11223, 11131, 11039, 10948, 10857, 10766, 10675, | ||
| 42 | 10585, 10495, 10406, 10316, 10227, 10139, 10050, 9962, 9874, 9787, 9700, 9613, 9526, 9440, 9354, 9269, 9184, 9099, | ||
| 43 | 9015, 8931, 8847, 8764, 8681, 8598, 8516, 8434, 8353, 8272, 8191, 8111, 8031, 7952, 7873, 7794, 7716, 7638, 7561, | ||
| 44 | 7484, 7407, 7331, 7255, 7180, 7105, 7031, 6957, 6883, 6810, 6738, 6665, 6594, 6522, 6451, 6381, 6311, 6241, 6172, | ||
| 45 | 6104, 6036, 5968, 5901, 5834, 5767, 5702, 5636, 5571, 5507, 5443, 5379, 5316, 5253, 5191, 5130, 5068, 5008, 4947, | ||
| 46 | 4888, 4828, 4769, 4711, 4653, 4596, 4539, 4482, 4426, 4371, 4316, 4261, 4207, 4153, 4100, 4047, 3995, 3943, 3892, | ||
| 47 | 3841, 3791, 3741, 3691, 3642, 3594, 3546, 3498, 3451, 3404, 3358, 3312, 3267, 3222, 3178, 3134, 3090, 3047, 3005, | ||
| 48 | 2962, 2921, 2879, 2839, 2798, 2758, 2719, 2680, 2641, 2603, 2565, 2528, 2491, 2454, 2418, 2382, 2347, 2312, 2278, | ||
| 49 | 2244, 2210, 2177, 2144, 2112, 2080, 2048, 2017, 1986, 1956, 1926, 1896, 1867, 1838, 1810, 1781, 1754, 1726, 1699, | ||
| 50 | 1673, 1646, 1620, 1595, 1570, 1545, 1520, 1496, 1472, 1449, 1426, 1403, 1380, 1358, 1336, 1315, 1294, 1273, 1252, | ||
| 51 | 1232, 1212, 1192, 1173, 1154, 1135, 1117, 1099, 1081, 1063, 1046, 1029, 1012, 996, 980, 964, 948, 933, 918, 903, | ||
| 52 | 888, 874, 860, 846, 833, 819, 806, 793, 781, 768, 756, 744, 733, 721, 710, 699, 688, 677, 667, 657, 647, 637, 627, | ||
| 53 | 618, 609, 599, 591, 582, 574, 565, 557, 549, 541, 534, 526, 519, 512, 505, 498, 492, 485, 479, 473, 467, 461, 455, | ||
| 54 | 450, 444, 439, 434, 429, 424, 419, 415, 410, 406, 402, 398, 394, 390, 386, 383, 379, 376, 373, 370, 367, 364, 361, | ||
| 55 | 359, 356, 354, 351, 349, 347, 345, 343, 342, 340, 338, 337, 336, 334, 333, 332, 331, 330, 330, 329, 328, 328, 328, | ||
| 56 | 327, 327, 327, 327, 327, 328, 328, 328, 329, 330, 330, 331, 332, 333, 334, 336, 337, 338, 340, 342, 343, 345, 347, | ||
| 57 | 349, 351, 354, 356, 359, 361, 364, 367, 370, 373, 376, 379, 383, 386, 390, 394, 398, 402, 406, 410, 415, 419, 424, | ||
| 58 | 429, 434, 439, 444, 450, 455, 461, 467, 473, 479, 485, 492, 498, 505, 512, 519, 526, 534, 541, 549, 557, 565, 574, | ||
| 59 | 582, 591, 599, 609, 618, 627, 637, 647, 657, 667, 677, 688, 699, 710, 721, 733, 744, 756, 768, 781, 793, 806, 819, | ||
| 60 | 833, 846, 860, 874, 888, 903, 918, 933, 948, 964, 980, 996, 1012, 1029, 1046, 1063, 1081, 1099, 1117, 1135, 1154, | ||
| 61 | 1173, 1192, 1212, 1232, 1252, 1273, 1294, 1315, 1336, 1358, 1380, 1403, 1426, 1449, 1472, 1496, 1520, 1545, 1570, | ||
| 62 | 1595, 1620, 1646, 1673, 1699, 1726, 1754, 1781, 1810, 1838, 1867, 1896, 1926, 1956, 1986, 2017, 2048, 2080, 2112, | ||
| 63 | 2144, 2177, 2210, 2244, 2278, 2312, 2347, 2382, 2418, 2454, 2491, 2528, 2565, 2603, 2641, 2680, 2719, 2758, 2798, | ||
| 64 | 2839, 2879, 2921, 2962, 3005, 3047, 3090, 3134, 3178, 3222, 3267, 3312, 3358, 3404, 3451, 3498, 3546, 3594, 3642, | ||
| 65 | 3691, 3741, 3791, 3841, 3892, 3943, 3995, 4047, 4100, 4153, 4207, 4261, 4316, 4371, 4426, 4482, 4539, 4596, 4653, | ||
| 66 | 4711, 4769, 4828, 4888, 4947, 5008, 5068, 5130, 5191, 5253, 5316, 5379, 5443, 5507, 5571, 5636, 5702, 5767, 5834, | ||
| 67 | 5901, 5968, 6036, 6104, 6172, 6241, 6311, 6381, 6451, 6522, 6594, 6665, 6738, 6810, 6883, 6957, 7031, 7105, 7180, | ||
| 68 | 7255, 7331, 7407, 7484, 7561, 7638, 7716, 7794, 7873, 7952, 8031, 8111, | ||
| 69 | ]; | ||
| 70 | |||
| 71 | #[embassy_executor::main] | ||
| 72 | async fn main(_spawner: Spawner) { | ||
| 73 | let p = embassy_nrf::init(Default::default()); | ||
| 74 | let mut pwm = SimplePwm::new_2ch(p.PWM20, p.P1_10, p.P1_14, &Default::default()); | ||
| 75 | pwm.set_prescaler(Prescaler::Div1); | ||
| 76 | pwm.set_max_duty(32767); | ||
| 77 | info!("pwm initialized!"); | ||
| 78 | |||
| 79 | let mut i = 0; | ||
| 80 | loop { | ||
| 81 | i += 1; | ||
| 82 | pwm.set_duty(0, DutyCycle::normal(DUTY[i % 1024])); | ||
| 83 | pwm.set_duty(1, DutyCycle::normal(DUTY[(i + 512) % 1024])); | ||
| 84 | Timer::after_millis(3).await; | ||
| 85 | } | ||
| 86 | } | ||
diff --git a/examples/nrf54l15/src/bin/saadc.rs b/examples/nrf54l15/src/bin/saadc.rs new file mode 100644 index 000000000..567177894 --- /dev/null +++ b/examples/nrf54l15/src/bin/saadc.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::info; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; | ||
| 7 | use embassy_nrf::{bind_interrupts, saadc}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | bind_interrupts!(struct Irqs { | ||
| 12 | SAADC => saadc::InterruptHandler; | ||
| 13 | }); | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_p: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let config = Config::default(); | ||
| 19 | let channel_config = ChannelConfig::single_ended(p.P1_04.reborrow()); | ||
| 20 | let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]); | ||
| 21 | |||
| 22 | loop { | ||
| 23 | let mut buf = [0; 1]; | ||
| 24 | saadc.sample(&mut buf).await; | ||
| 25 | info!("sample: {=i16}", &buf[0]); | ||
| 26 | Timer::after_millis(100).await; | ||
| 27 | } | ||
| 28 | } | ||
diff --git a/examples/nrf54l15/src/bin/spim.rs b/examples/nrf54l15/src/bin/spim.rs new file mode 100644 index 000000000..3f5980647 --- /dev/null +++ b/examples/nrf54l15/src/bin/spim.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::{bind_interrupts, peripherals, spim}; | ||
| 6 | use {defmt_rtt as _, panic_probe as _}; | ||
| 7 | |||
| 8 | bind_interrupts!(struct Irqs { | ||
| 9 | SERIAL00 => spim::InterruptHandler<peripherals::SERIAL00>; | ||
| 10 | }); | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | let p = embassy_nrf::init(Default::default()); | ||
| 15 | let mut config = spim::Config::default(); | ||
| 16 | config.frequency = spim::Frequency::M32; | ||
| 17 | let mut spim = spim::Spim::new(p.SERIAL00, Irqs, p.P2_05, p.P2_09, p.P2_08, config.clone()); | ||
| 18 | let data = [ | ||
| 19 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 20 | ]; | ||
| 21 | let mut buf = [0u8; 16]; | ||
| 22 | |||
| 23 | buf.fill(0); | ||
| 24 | spim.blocking_transfer(&mut buf, &data).unwrap(); | ||
| 25 | assert_eq!(data, buf); | ||
| 26 | |||
| 27 | buf.fill(0); | ||
| 28 | spim.transfer(&mut buf, &data).await.unwrap(); | ||
| 29 | assert_eq!(data, buf); | ||
| 30 | } | ||
diff --git a/examples/nrf54l15/src/bin/twim.rs b/examples/nrf54l15/src/bin/twim.rs new file mode 100644 index 000000000..53b85034e --- /dev/null +++ b/examples/nrf54l15/src/bin/twim.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | //! Example on how to read a 24C/24LC i2c eeprom. | ||
| 2 | //! | ||
| 3 | //! Connect SDA to P0.03, SCL to P0.04 | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_nrf::twim::{self, Twim}; | ||
| 11 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 12 | use static_cell::ConstStaticCell; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | const ADDRESS: u8 = 0x18; | ||
| 16 | const WHOAMI: u8 = 0x0F; | ||
| 17 | |||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | SERIAL20 => twim::InterruptHandler<peripherals::SERIAL20>; | ||
| 20 | }); | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async fn main(_spawner: Spawner) { | ||
| 24 | let p = embassy_nrf::init(Default::default()); | ||
| 25 | info!("Initializing TWI..."); | ||
| 26 | let config = twim::Config::default(); | ||
| 27 | static RAM_BUFFER: ConstStaticCell<[u8; 16]> = ConstStaticCell::new([0; 16]); | ||
| 28 | let mut twi = Twim::new(p.SERIAL20, Irqs, p.P1_13, p.P1_12, config, RAM_BUFFER.take()); | ||
| 29 | |||
| 30 | info!("Reading..."); | ||
| 31 | |||
| 32 | let mut data = [0u8; 1]; | ||
| 33 | match twi.write_read(ADDRESS, &[WHOAMI], &mut data).await { | ||
| 34 | Ok(()) => info!("Whoami: {}", data[0]), | ||
| 35 | Err(e) => error!("I2c Error: {:?}", e), | ||
| 36 | } | ||
| 37 | } | ||
diff --git a/examples/nrf54l15/src/bin/twis.rs b/examples/nrf54l15/src/bin/twis.rs new file mode 100644 index 000000000..34c04aee3 --- /dev/null +++ b/examples/nrf54l15/src/bin/twis.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | //! TWIS example | ||
| 2 | |||
| 3 | #![no_std] | ||
| 4 | #![no_main] | ||
| 5 | |||
| 6 | use defmt::*; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_nrf::twis::{self, Command, Twis}; | ||
| 9 | use embassy_nrf::{bind_interrupts, peripherals}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | SERIAL20 => twis::InterruptHandler<peripherals::SERIAL20>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let p = embassy_nrf::init(Default::default()); | ||
| 19 | |||
| 20 | let mut config = twis::Config::default(); | ||
| 21 | config.address0 = 0x55; // Set i2c address | ||
| 22 | let mut i2c = Twis::new(p.SERIAL20, Irqs, p.P0_03, p.P0_04, config); | ||
| 23 | |||
| 24 | info!("Listening..."); | ||
| 25 | loop { | ||
| 26 | let response = [1, 2, 3, 4, 5, 6, 7, 8]; | ||
| 27 | // This buffer is used if the i2c master performs a Write or WriteRead | ||
| 28 | let mut buf = [0u8; 16]; | ||
| 29 | match i2c.listen(&mut buf).await { | ||
| 30 | Ok(Command::Read) => { | ||
| 31 | info!("Got READ command. Respond with data:\n{:?}\n", response); | ||
| 32 | if let Err(e) = i2c.respond_to_read(&response).await { | ||
| 33 | error!("{:?}", e); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | Ok(Command::Write(n)) => info!("Got WRITE command with data:\n{:?}\n", buf[..n]), | ||
| 37 | Ok(Command::WriteRead(n)) => { | ||
| 38 | info!("Got WRITE/READ command with data:\n{:?}", buf[..n]); | ||
| 39 | info!("Respond with data:\n{:?}\n", response); | ||
| 40 | if let Err(e) = i2c.respond_to_read(&response).await { | ||
| 41 | error!("{:?}", e); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | Err(e) => error!("{:?}", e), | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
diff --git a/examples/nrf54l15/src/bin/uart.rs b/examples/nrf54l15/src/bin/uart.rs new file mode 100644 index 000000000..cc6528a6f --- /dev/null +++ b/examples/nrf54l15/src/bin/uart.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 7 | use {defmt_rtt as _, panic_probe as _}; | ||
| 8 | |||
| 9 | bind_interrupts!(struct Irqs { | ||
| 10 | SERIAL20 => uarte::InterruptHandler<peripherals::SERIAL20>; | ||
| 11 | }); | ||
| 12 | |||
| 13 | #[embassy_executor::main] | ||
| 14 | async fn main(_spawner: Spawner) { | ||
| 15 | let p = embassy_nrf::init(Default::default()); | ||
| 16 | let mut config = uarte::Config::default(); | ||
| 17 | config.parity = uarte::Parity::EXCLUDED; | ||
| 18 | config.baudrate = uarte::Baudrate::BAUD115200; | ||
| 19 | |||
| 20 | let mut uart = uarte::Uarte::new(p.SERIAL20, p.P1_12, p.P1_13, Irqs, config); | ||
| 21 | |||
| 22 | info!("uarte initialized!"); | ||
| 23 | |||
| 24 | // Message must be in SRAM | ||
| 25 | let mut buf = [0; 8]; | ||
| 26 | buf.copy_from_slice(b"Hello!\r\n"); | ||
| 27 | |||
| 28 | unwrap!(uart.write(&buf).await); | ||
| 29 | info!("wrote hello in uart!"); | ||
| 30 | |||
| 31 | loop { | ||
| 32 | info!("reading..."); | ||
| 33 | unwrap!(uart.read(&mut buf).await); | ||
| 34 | info!("writing..."); | ||
| 35 | unwrap!(uart.write(&buf).await); | ||
| 36 | } | ||
| 37 | } | ||
diff --git a/tests/nrf/.cargo/config.toml b/tests/nrf/.cargo/config.toml index 8f9bccbc0..0192c10ae 100644 --- a/tests/nrf/.cargo/config.toml +++ b/tests/nrf/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 2 | #runner = "teleprobe local run --chip nRF52840_xxAA --elf" | 2 | runner = "teleprobe local run --chip nRF52840_xxAA --elf" |
| 3 | runner = "teleprobe client run" | 3 | #runner = "teleprobe client run" |
| 4 | 4 | ||
| 5 | [build] | 5 | [build] |
| 6 | #target = "thumbv6m-none-eabi" | 6 | #target = "thumbv6m-none-eabi" |
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 24ddd06f3..6d862e19d 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs | |||
| @@ -55,14 +55,14 @@ async fn main(_spawner: Spawner) { | |||
| 55 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | 55 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 56 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); | 56 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); |
| 57 | let spam_peri = pac::UARTE1; | 57 | let spam_peri = pac::UARTE1; |
| 58 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_endtx().as_ptr())) }; | 58 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(spam_peri.events_dma().tx().end().as_ptr())) }; |
| 59 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_starttx().as_ptr())) }; | 59 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(spam_peri.tasks_dma().tx().start().as_ptr())) }; |
| 60 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); | 60 | let mut spam_ppi = Ppi::new_one_to_one(p.PPI_CH2, event, task); |
| 61 | spam_ppi.enable(); | 61 | spam_ppi.enable(); |
| 62 | let p = (&raw mut TX_BUF) as *mut u8; | 62 | let p = (&raw mut TX_BUF) as *mut u8; |
| 63 | spam_peri.txd().ptr().write_value(p as u32); | 63 | spam_peri.dma().tx().ptr().write_value(p as u32); |
| 64 | spam_peri.txd().maxcnt().write(|w| w.set_maxcnt(NSPAM as _)); | 64 | spam_peri.dma().tx().maxcnt().write(|w| w.set_maxcnt(NSPAM as _)); |
| 65 | spam_peri.tasks_starttx().write_value(1); | 65 | spam_peri.tasks_dma().tx().start().write_value(1); |
| 66 | 66 | ||
| 67 | let mut i = 0; | 67 | let mut i = 0; |
| 68 | let mut total = 0; | 68 | let mut total = 0; |
