aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-28 22:41:45 +0200
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:58 +0200
commit3a18373828577e5e9d06e9f5c108376fef32fe18 (patch)
tree3712adfb3061029914bc63a47231beebf49b9c2f
parent00e5f3035219656823ec7a2451f4ebae6802e1b8 (diff)
nrf/uarte: update BufferedUarte to new APi
-rw-r--r--embassy-nrf-examples/src/bin/buffered_uart.rs80
-rw-r--r--embassy-nrf/Cargo.toml16
-rw-r--r--embassy-nrf/src/buffered_uarte.rs287
-rw-r--r--embassy-nrf/src/lib.rs11
4 files changed, 173 insertions, 221 deletions
diff --git a/embassy-nrf-examples/src/bin/buffered_uart.rs b/embassy-nrf-examples/src/bin/buffered_uart.rs
index c70171280..80b24d2ba 100644
--- a/embassy-nrf-examples/src/bin/buffered_uart.rs
+++ b/embassy-nrf-examples/src/bin/buffered_uart.rs
@@ -7,54 +7,49 @@
7 7
8#[path = "../example_common.rs"] 8#[path = "../example_common.rs"]
9mod example_common; 9mod example_common;
10use core::mem;
11
12use embassy_nrf::gpio::NoPin;
10use example_common::*; 13use example_common::*;
11 14
12use cortex_m_rt::entry; 15use cortex_m_rt::entry;
13use defmt::panic; 16use defmt::panic;
14use futures::pin_mut; 17use futures::pin_mut;
15use nrf52840_hal as hal; 18use nrf52840_hal::clocks;
16use nrf52840_hal::gpio;
17 19
18use embassy::executor::{task, Executor}; 20use embassy::executor::{task, Executor};
19use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; 21use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
20use embassy::util::Forever; 22use embassy::util::{Forever, Steal};
21use embassy_nrf::buffered_uarte; 23use embassy_nrf::{buffered_uarte::BufferedUarte, interrupt, peripherals, rtc, uarte, Peripherals};
22use embassy_nrf::interrupt;
23
24static mut TX_BUFFER: [u8; 4096] = [0; 4096];
25static mut RX_BUFFER: [u8; 4096] = [0; 4096];
26 24
27#[task] 25#[task]
28async fn run() { 26async fn run() {
29 let p = unwrap!(embassy_nrf::pac::Peripherals::take()); 27 let p = unsafe { Peripherals::steal() };
30
31 let port0 = gpio::p0::Parts::new(p.P0);
32
33 let pins = buffered_uarte::Pins {
34 rxd: port0.p0_08.into_floating_input().degrade(),
35 txd: port0
36 .p0_06
37 .into_push_pull_output(gpio::Level::Low)
38 .degrade(),
39 cts: None,
40 rts: None,
41 };
42 28
43 let ppi = hal::ppi::Parts::new(p.PPI); 29 let mut config = uarte::Config::default();
30 config.parity = uarte::Parity::EXCLUDED;
31 config.baudrate = uarte::Baudrate::BAUD115200;
32
33 let mut tx_buffer = [0u8; 4096];
34 let mut rx_buffer = [0u8; 4096];
44 35
45 let irq = interrupt::take!(UARTE0_UART0); 36 let irq = interrupt::take!(UARTE0_UART0);
46 let u = buffered_uarte::BufferedUarte::new( 37 let u = unsafe {
47 p.UARTE0, 38 BufferedUarte::new(
48 p.TIMER0, 39 p.UARTE0,
49 ppi.ppi0, 40 p.TIMER0,
50 ppi.ppi1, 41 p.PPI_CH0,
51 irq, 42 p.PPI_CH1,
52 unsafe { &mut RX_BUFFER }, 43 irq,
53 unsafe { &mut TX_BUFFER }, 44 p.P0_08,
54 pins, 45 p.P0_06,
55 buffered_uarte::Parity::EXCLUDED, 46 NoPin,
56 buffered_uarte::Baudrate::BAUD115200, 47 NoPin,
57 ); 48 config,
49 &mut rx_buffer,
50 &mut tx_buffer,
51 )
52 };
58 pin_mut!(u); 53 pin_mut!(u);
59 54
60 info!("uarte initialized!"); 55 info!("uarte initialized!");
@@ -80,13 +75,30 @@ async fn run() {
80 } 75 }
81} 76}
82 77
78static RTC: Forever<rtc::RTC<peripherals::RTC1>> = Forever::new();
79static ALARM: Forever<rtc::Alarm<peripherals::RTC1>> = Forever::new();
83static EXECUTOR: Forever<Executor> = Forever::new(); 80static EXECUTOR: Forever<Executor> = Forever::new();
84 81
85#[entry] 82#[entry]
86fn main() -> ! { 83fn main() -> ! {
87 info!("Hello World!"); 84 info!("Hello World!");
88 85
86 let p = unwrap!(embassy_nrf::Peripherals::take());
87
88 clocks::Clocks::new(unsafe { mem::transmute(()) })
89 .enable_ext_hfosc()
90 .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass)
91 .start_lfclk();
92
93 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
94 rtc.start();
95
96 unsafe { embassy::time::set_clock(rtc) };
97
98 let alarm = ALARM.put(rtc.alarm0());
89 let executor = EXECUTOR.put(Executor::new()); 99 let executor = EXECUTOR.put(Executor::new());
100 executor.set_alarm(alarm);
101
90 executor.run(|spawner| { 102 executor.run(|spawner| {
91 unwrap!(spawner.spawn(run())); 103 unwrap!(spawner.spawn(run()));
92 }); 104 });
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index f26e892d3..3ab2c60bd 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -11,11 +11,11 @@ defmt-info = [ ]
11defmt-warn = [ ] 11defmt-warn = [ ]
12defmt-error = [ ] 12defmt-error = [ ]
13 13
1452810 = ["nrf52810-pac", "nrf52810-hal"] 1452810 = ["nrf52810-pac"]
1552811 = ["nrf52811-pac"] #, "nrf52811-hal"] 1552811 = ["nrf52811-pac"]
1652832 = ["nrf52832-pac", "nrf52832-hal"] 1652832 = ["nrf52832-pac"]
1752833 = ["nrf52833-pac", "nrf52833-hal"] 1752833 = ["nrf52833-pac"]
1852840 = ["nrf52840-pac", "nrf52840-hal"] 1852840 = ["nrf52840-pac"]
19 19
20 20
21[dependencies] 21[dependencies]
@@ -36,9 +36,3 @@ nrf52811-pac = { version = "0.9.1", optional = true }
36nrf52832-pac = { version = "0.9.0", optional = true } 36nrf52832-pac = { version = "0.9.0", optional = true }
37nrf52833-pac = { version = "0.9.0", optional = true } 37nrf52833-pac = { version = "0.9.0", optional = true }
38nrf52840-pac = { version = "0.9.0", optional = true } 38nrf52840-pac = { version = "0.9.0", optional = true }
39
40nrf52810-hal = { version = "0.12.1", optional = true }
41#nrf52811-hal = { version = "0.12.1", optional = true } # doesn't exist yet
42nrf52832-hal = { version = "0.12.1", optional = true }
43nrf52833-hal = { version = "0.12.1", optional = true }
44nrf52840-hal = { version = "0.12.1", optional = true }
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 6cc5f1322..702ccde0e 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -1,30 +1,24 @@
1//! HAL interface to the UARTE peripheral
2//!
3//! See product specification:
4//!
5//! - nrf52832: Section 35
6//! - nrf52840: Section 6.34
7use core::cmp::min; 1use core::cmp::min;
8use core::mem; 2use core::mem;
9use core::ops::Deref;
10use core::pin::Pin; 3use core::pin::Pin;
11use core::sync::atomic::{compiler_fence, Ordering}; 4use core::sync::atomic::{compiler_fence, Ordering};
12use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
13use embassy::interrupt::InterruptExt; 6use embassy::interrupt::InterruptExt;
14use embassy::io::{AsyncBufRead, AsyncWrite, Result}; 7use embassy::io::{AsyncBufRead, AsyncWrite, Result};
15use embassy::util::WakerRegistration; 8use embassy::util::{PeripheralBorrow, WakerRegistration};
16use embassy_extras::low_power_wait_until;
17use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; 9use embassy_extras::peripheral::{PeripheralMutex, PeripheralState};
18use embassy_extras::ring_buffer::RingBuffer; 10use embassy_extras::ring_buffer::RingBuffer;
19use embedded_hal::digital::v2::OutputPin; 11use embassy_extras::{low_power_wait_until, unborrow};
20 12
21use crate::fmt::*; 13use crate::fmt::{panic, *};
22use crate::hal::ppi::ConfigurablePpi; 14use crate::gpio::sealed::Pin as _;
23use crate::interrupt::{self, Interrupt}; 15use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin};
24use crate::pac; 16use crate::pac;
17use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
18use crate::timer::Instance as TimerInstance;
19use crate::uarte::{Config, Instance as UarteInstance};
25 20
26// Re-export SVD variants to allow user to directly set values 21// Re-export SVD variants to allow user to directly set values
27pub use crate::hal::uarte::Pins;
28pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; 22pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
29 23
30#[derive(Copy, Clone, Debug, PartialEq)] 24#[derive(Copy, Clone, Debug, PartialEq)]
@@ -39,17 +33,17 @@ enum TxState {
39 Transmitting(usize), 33 Transmitting(usize),
40} 34}
41 35
42struct State<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> { 36struct State<'d, U: UarteInstance, T: TimerInstance> {
43 uarte: U, 37 uarte: U,
44 timer: T, 38 timer: T,
45 ppi_channel_1: P1, 39 _ppi_ch1: Ppi<'d, AnyConfigurableChannel>,
46 ppi_channel_2: P2, 40 _ppi_ch2: Ppi<'d, AnyConfigurableChannel>,
47 41
48 rx: RingBuffer<'a>, 42 rx: RingBuffer<'d>,
49 rx_state: RxState, 43 rx_state: RxState,
50 rx_waker: WakerRegistration, 44 rx_waker: WakerRegistration,
51 45
52 tx: RingBuffer<'a>, 46 tx: RingBuffer<'d>,
53 tx_state: TxState, 47 tx_state: TxState,
54 tx_waker: WakerRegistration, 48 tx_waker: WakerRegistration,
55} 49}
@@ -62,115 +56,112 @@ struct State<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: Configu
62/// are disabled before using `Uarte`. See product specification: 56/// are disabled before using `Uarte`. See product specification:
63/// - nrf52832: Section 15.2 57/// - nrf52832: Section 15.2
64/// - nrf52840: Section 6.1.2 58/// - nrf52840: Section 6.1.2
65pub struct BufferedUarte< 59pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
66 'a, 60 inner: PeripheralMutex<State<'d, U, T>>,
67 U: Instance,
68 T: TimerInstance,
69 P1: ConfigurablePpi,
70 P2: ConfigurablePpi,
71> {
72 inner: PeripheralMutex<State<'a, U, T, P1, P2>>,
73} 61}
74 62
75impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> 63impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
76 BufferedUarte<'a, U, T, P1, P2> 64 /// unsafe: may not leak self or futures
77{ 65 pub unsafe fn new(
78 pub fn new( 66 uarte: impl PeripheralBorrow<Target = U> + 'd,
79 uarte: U, 67 timer: impl PeripheralBorrow<Target = T> + 'd,
80 timer: T, 68 ppi_ch1: impl PeripheralBorrow<Target = impl ConfigurableChannel> + 'd,
81 mut ppi_channel_1: P1, 69 ppi_ch2: impl PeripheralBorrow<Target = impl ConfigurableChannel> + 'd,
82 mut ppi_channel_2: P2, 70 irq: impl PeripheralBorrow<Target = U::Interrupt> + 'd,
83 irq: U::Interrupt, 71 rxd: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
84 rx_buffer: &'a mut [u8], 72 txd: impl PeripheralBorrow<Target = impl GpioPin> + 'd,
85 tx_buffer: &'a mut [u8], 73 cts: impl PeripheralBorrow<Target = impl GpioOptionalPin> + 'd,
86 mut pins: Pins, 74 rts: impl PeripheralBorrow<Target = impl GpioOptionalPin> + 'd,
87 parity: Parity, 75 config: Config,
88 baudrate: Baudrate, 76 rx_buffer: &'d mut [u8],
77 tx_buffer: &'d mut [u8],
89 ) -> Self { 78 ) -> Self {
90 // Select pins 79 unborrow!(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts);
91 uarte.psel.rxd.write(|w| {
92 unsafe { w.bits(pins.rxd.psel_bits()) };
93 w.connect().connected()
94 });
95 pins.txd.set_high().unwrap();
96 uarte.psel.txd.write(|w| {
97 unsafe { w.bits(pins.txd.psel_bits()) };
98 w.connect().connected()
99 });
100 80
101 // Optional pins 81 let r = uarte.regs();
102 uarte.psel.cts.write(|w| { 82 let rt = timer.regs();
103 if let Some(ref pin) = pins.cts {
104 unsafe { w.bits(pin.psel_bits()) };
105 w.connect().connected()
106 } else {
107 w.connect().disconnected()
108 }
109 });
110 83
111 uarte.psel.rts.write(|w| { 84 rxd.conf().write(|w| w.input().connect().drive().h0h1());
112 if let Some(ref pin) = pins.rts { 85 r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
113 unsafe { w.bits(pin.psel_bits()) };
114 w.connect().connected()
115 } else {
116 w.connect().disconnected()
117 }
118 });
119 86
120 // Enable UARTE instance 87 txd.set_high();
121 uarte.enable.write(|w| w.enable().enabled()); 88 txd.conf().write(|w| w.dir().output().drive().h0h1());
89 r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
122 90
123 // Enable interrupts 91 if let Some(pin) = rts.pin_mut() {
124 uarte.intenset.write(|w| w.endrx().set().endtx().set()); 92 pin.set_high();
93 pin.conf().write(|w| w.dir().output().drive().h0h1());
94 }
95 r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
96
97 if let Some(pin) = cts.pin_mut() {
98 pin.conf().write(|w| w.input().connect().drive().h0h1());
99 }
100 r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
101
102 r.baudrate.write(|w| w.baudrate().variant(config.baudrate));
103 r.config.write(|w| w.parity().variant(config.parity));
125 104
126 // Configure 105 // Configure
127 let hardware_flow_control = pins.rts.is_some() && pins.cts.is_some(); 106 let hardware_flow_control = match (rts.pin().is_some(), cts.pin().is_some()) {
128 uarte 107 (false, false) => false,
129 .config 108 (true, true) => true,
130 .write(|w| w.hwfc().bit(hardware_flow_control).parity().variant(parity)); 109 _ => panic!("RTS and CTS pins must be either both set or none set."),
110 };
111 r.config.write(|w| {
112 w.hwfc().bit(hardware_flow_control);
113 w.parity().variant(config.parity);
114 w
115 });
116 r.baudrate.write(|w| w.baudrate().variant(config.baudrate));
131 117
132 // Configure frequency 118 // Enable interrupts
133 uarte.baudrate.write(|w| w.baudrate().variant(baudrate)); 119 r.intenset.write(|w| w.endrx().set().endtx().set());
134 120
135 // Disable the irq, let the Registration enable it when everything is set up. 121 // Disable the irq, let the Registration enable it when everything is set up.
136 irq.disable(); 122 irq.disable();
137 irq.pend(); 123 irq.pend();
138 124
125 // Enable UARTE instance
126 r.enable.write(|w| w.enable().enabled());
127
139 // BAUDRATE register values are `baudrate * 2^32 / 16000000` 128 // BAUDRATE register values are `baudrate * 2^32 / 16000000`
140 // source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values 129 // source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values
141 // 130 //
142 // We want to stop RX if line is idle for 2 bytes worth of time 131 // We want to stop RX if line is idle for 2 bytes worth of time
143 // That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit) 132 // That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit)
144 // This gives us the amount of 16M ticks for 20 bits. 133 // This gives us the amount of 16M ticks for 20 bits.
145 let timeout = 0x8000_0000 / (baudrate as u32 / 40); 134 let timeout = 0x8000_0000 / (config.baudrate as u32 / 40);
146 135
147 timer.tasks_stop.write(|w| unsafe { w.bits(1) }); 136 rt.tasks_stop.write(|w| unsafe { w.bits(1) });
148 timer.bitmode.write(|w| w.bitmode()._32bit()); 137 rt.bitmode.write(|w| w.bitmode()._32bit());
149 timer.prescaler.write(|w| unsafe { w.prescaler().bits(0) }); 138 rt.prescaler.write(|w| unsafe { w.prescaler().bits(0) });
150 timer.cc[0].write(|w| unsafe { w.bits(timeout) }); 139 rt.cc[0].write(|w| unsafe { w.bits(timeout) });
151 timer.mode.write(|w| w.mode().timer()); 140 rt.mode.write(|w| w.mode().timer());
152 timer.shorts.write(|w| { 141 rt.shorts.write(|w| {
153 w.compare0_clear().set_bit(); 142 w.compare0_clear().set_bit();
154 w.compare0_stop().set_bit(); 143 w.compare0_stop().set_bit();
155 w 144 w
156 }); 145 });
157 146
158 ppi_channel_1.set_event_endpoint(&uarte.events_rxdrdy); 147 let mut ppi_ch1 = Ppi::new(ppi_ch1.degrade_configurable());
159 ppi_channel_1.set_task_endpoint(&timer.tasks_clear); 148 ppi_ch1.set_event(Event::from_reg(&r.events_rxdrdy));
160 ppi_channel_1.set_fork_task_endpoint(&timer.tasks_start); 149 ppi_ch1.set_task(Task::from_reg(&rt.tasks_clear));
161 ppi_channel_1.enable(); 150 ppi_ch1.set_fork_task(Task::from_reg(&rt.tasks_start));
151 ppi_ch1.enable();
162 152
163 ppi_channel_2.set_event_endpoint(&timer.events_compare[0]); 153 let mut ppi_ch2 = Ppi::new(ppi_ch2.degrade_configurable());
164 ppi_channel_2.set_task_endpoint(&uarte.tasks_stoprx); 154 ppi_ch2.set_event(Event::from_reg(&rt.events_compare[0]));
165 ppi_channel_2.enable(); 155 ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx));
156 ppi_ch2.enable();
166 157
167 BufferedUarte { 158 BufferedUarte {
168 inner: PeripheralMutex::new( 159 inner: PeripheralMutex::new(
169 State { 160 State {
170 uarte, 161 uarte,
171 timer, 162 timer,
172 ppi_channel_1, 163 _ppi_ch1: ppi_ch1,
173 ppi_channel_2, 164 _ppi_ch2: ppi_ch2,
174 165
175 rx: RingBuffer::new(rx_buffer), 166 rx: RingBuffer::new(rx_buffer),
176 rx_state: RxState::Idle, 167 rx_state: RxState::Idle,
@@ -187,25 +178,23 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
187 178
188 pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) { 179 pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) {
189 self.inner().with(|state, _irq| { 180 self.inner().with(|state, _irq| {
181 let r = state.uarte.regs();
182 let rt = state.timer.regs();
183
190 let timeout = 0x8000_0000 / (baudrate as u32 / 40); 184 let timeout = 0x8000_0000 / (baudrate as u32 / 40);
191 state.timer.cc[0].write(|w| unsafe { w.bits(timeout) }); 185 rt.cc[0].write(|w| unsafe { w.bits(timeout) });
192 state.timer.tasks_clear.write(|w| unsafe { w.bits(1) }); 186 rt.tasks_clear.write(|w| unsafe { w.bits(1) });
193 187
194 state 188 r.baudrate.write(|w| w.baudrate().variant(baudrate));
195 .uarte
196 .baudrate
197 .write(|w| w.baudrate().variant(baudrate));
198 }); 189 });
199 } 190 }
200 191
201 fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex<State<'a, U, T, P1, P2>>> { 192 fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex<State<'d, U, T>>> {
202 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } 193 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }
203 } 194 }
204} 195}
205 196
206impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> AsyncBufRead 197impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> {
207 for BufferedUarte<'a, U, T, P1, P2>
208{
209 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { 198 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
210 let mut inner = self.inner(); 199 let mut inner = self.inner();
211 inner.as_mut().register_interrupt(); 200 inner.as_mut().register_interrupt();
@@ -242,9 +231,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
242 } 231 }
243} 232}
244 233
245impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> AsyncWrite 234impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, T> {
246 for BufferedUarte<'a, U, T, P1, P2>
247{
248 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> { 235 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
249 let mut inner = self.inner(); 236 let mut inner = self.inner();
250 inner.as_mut().register_interrupt(); 237 inner.as_mut().register_interrupt();
@@ -276,32 +263,36 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
276 } 263 }
277} 264}
278 265
279impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> Drop 266impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> {
280 for State<'a, U, T, P1, P2>
281{
282 fn drop(&mut self) { 267 fn drop(&mut self) {
283 self.timer.tasks_stop.write(|w| unsafe { w.bits(1) }); 268 let r = self.uarte.regs();
269 let rt = self.timer.regs();
270
271 // TODO this probably deadlocks. do like Uarte instead.
272
273 rt.tasks_stop.write(|w| unsafe { w.bits(1) });
284 if let RxState::Receiving = self.rx_state { 274 if let RxState::Receiving = self.rx_state {
285 self.uarte.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 275 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
286 } 276 }
287 if let TxState::Transmitting(_) = self.tx_state { 277 if let TxState::Transmitting(_) = self.tx_state {
288 self.uarte.tasks_stoptx.write(|w| unsafe { w.bits(1) }); 278 r.tasks_stoptx.write(|w| unsafe { w.bits(1) });
289 } 279 }
290 if let RxState::Receiving = self.rx_state { 280 if let RxState::Receiving = self.rx_state {
291 low_power_wait_until(|| self.uarte.events_endrx.read().bits() == 1); 281 low_power_wait_until(|| r.events_endrx.read().bits() == 1);
292 } 282 }
293 if let TxState::Transmitting(_) = self.tx_state { 283 if let TxState::Transmitting(_) = self.tx_state {
294 low_power_wait_until(|| self.uarte.events_endtx.read().bits() == 1); 284 low_power_wait_until(|| r.events_endtx.read().bits() == 1);
295 } 285 }
296 } 286 }
297} 287}
298 288
299impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> PeripheralState 289impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for State<'a, U, T> {
300 for State<'a, U, T, P1, P2>
301{
302 type Interrupt = U::Interrupt; 290 type Interrupt = U::Interrupt;
303 fn on_interrupt(&mut self) { 291 fn on_interrupt(&mut self) {
304 trace!("irq: start"); 292 trace!("irq: start");
293 let r = self.uarte.regs();
294 let rt = self.timer.regs();
295
305 loop { 296 loop {
306 match self.rx_state { 297 match self.rx_state {
307 RxState::Idle => { 298 RxState::Idle => {
@@ -313,11 +304,11 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
313 self.rx_state = RxState::Receiving; 304 self.rx_state = RxState::Receiving;
314 305
315 // Set up the DMA read 306 // Set up the DMA read
316 self.uarte.rxd.ptr.write(|w| 307 r.rxd.ptr.write(|w|
317 // The PTR field is a full 32 bits wide and accepts the full range 308 // The PTR field is a full 32 bits wide and accepts the full range
318 // of values. 309 // of values.
319 unsafe { w.ptr().bits(buf.as_ptr() as u32) }); 310 unsafe { w.ptr().bits(buf.as_ptr() as u32) });
320 self.uarte.rxd.maxcnt.write(|w| 311 r.rxd.maxcnt.write(|w|
321 // We're giving it the length of the buffer, so no danger of 312 // We're giving it the length of the buffer, so no danger of
322 // accessing invalid memory. We have verified that the length of the 313 // accessing invalid memory. We have verified that the length of the
323 // buffer fits in an `u8`, so the cast to `u8` is also fine. 314 // buffer fits in an `u8`, so the cast to `u8` is also fine.
@@ -328,7 +319,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
328 trace!(" irq_rx: buf {:?} {:?}", buf.as_ptr() as u32, buf.len()); 319 trace!(" irq_rx: buf {:?} {:?}", buf.as_ptr() as u32, buf.len());
329 320
330 // Start UARTE Receive transaction 321 // Start UARTE Receive transaction
331 self.uarte.tasks_startrx.write(|w| 322 r.tasks_startrx.write(|w|
332 // `1` is a valid value to write to task registers. 323 // `1` is a valid value to write to task registers.
333 unsafe { w.bits(1) }); 324 unsafe { w.bits(1) });
334 } 325 }
@@ -336,14 +327,14 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
336 } 327 }
337 RxState::Receiving => { 328 RxState::Receiving => {
338 trace!(" irq_rx: in state receiving"); 329 trace!(" irq_rx: in state receiving");
339 if self.uarte.events_endrx.read().bits() != 0 { 330 if r.events_endrx.read().bits() != 0 {
340 self.timer.tasks_stop.write(|w| unsafe { w.bits(1) }); 331 rt.tasks_stop.write(|w| unsafe { w.bits(1) });
341 332
342 let n: usize = self.uarte.rxd.amount.read().amount().bits() as usize; 333 let n: usize = r.rxd.amount.read().amount().bits() as usize;
343 trace!(" irq_rx: endrx {:?}", n); 334 trace!(" irq_rx: endrx {:?}", n);
344 self.rx.push(n); 335 self.rx.push(n);
345 336
346 self.uarte.events_endrx.reset(); 337 r.events_endrx.reset();
347 338
348 self.rx_waker.wake(); 339 self.rx_waker.wake();
349 self.rx_state = RxState::Idle; 340 self.rx_state = RxState::Idle;
@@ -364,11 +355,11 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
364 self.tx_state = TxState::Transmitting(buf.len()); 355 self.tx_state = TxState::Transmitting(buf.len());
365 356
366 // Set up the DMA write 357 // Set up the DMA write
367 self.uarte.txd.ptr.write(|w| 358 r.txd.ptr.write(|w|
368 // The PTR field is a full 32 bits wide and accepts the full range 359 // The PTR field is a full 32 bits wide and accepts the full range
369 // of values. 360 // of values.
370 unsafe { w.ptr().bits(buf.as_ptr() as u32) }); 361 unsafe { w.ptr().bits(buf.as_ptr() as u32) });
371 self.uarte.txd.maxcnt.write(|w| 362 r.txd.maxcnt.write(|w|
372 // We're giving it the length of the buffer, so no danger of 363 // We're giving it the length of the buffer, so no danger of
373 // accessing invalid memory. We have verified that the length of the 364 // accessing invalid memory. We have verified that the length of the
374 // buffer fits in an `u8`, so the cast to `u8` is also fine. 365 // buffer fits in an `u8`, so the cast to `u8` is also fine.
@@ -378,7 +369,7 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
378 unsafe { w.maxcnt().bits(buf.len() as _) }); 369 unsafe { w.maxcnt().bits(buf.len() as _) });
379 370
380 // Start UARTE Transmit transaction 371 // Start UARTE Transmit transaction
381 self.uarte.tasks_starttx.write(|w| 372 r.tasks_starttx.write(|w|
382 // `1` is a valid value to write to task registers. 373 // `1` is a valid value to write to task registers.
383 unsafe { w.bits(1) }); 374 unsafe { w.bits(1) });
384 } 375 }
@@ -386,8 +377,8 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
386 } 377 }
387 TxState::Transmitting(n) => { 378 TxState::Transmitting(n) => {
388 trace!(" irq_tx: in state Transmitting"); 379 trace!(" irq_tx: in state Transmitting");
389 if self.uarte.events_endtx.read().bits() != 0 { 380 if r.events_endtx.read().bits() != 0 {
390 self.uarte.events_endtx.reset(); 381 r.events_endtx.reset();
391 382
392 trace!(" irq_tx: endtx {:?}", n); 383 trace!(" irq_tx: endtx {:?}", n);
393 self.tx.pop(n); 384 self.tx.pop(n);
@@ -402,37 +393,3 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
402 trace!("irq: end"); 393 trace!("irq: end");
403 } 394 }
404} 395}
405
406mod sealed {
407 pub trait Instance {}
408
409 impl Instance for crate::pac::UARTE0 {}
410 #[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
411 impl Instance for crate::pac::UARTE1 {}
412
413 pub trait TimerInstance {}
414 impl TimerInstance for crate::pac::TIMER0 {}
415 impl TimerInstance for crate::pac::TIMER1 {}
416 impl TimerInstance for crate::pac::TIMER2 {}
417}
418
419pub trait Instance: Deref<Target = pac::uarte0::RegisterBlock> + sealed::Instance {
420 type Interrupt: Interrupt;
421}
422
423impl Instance for pac::UARTE0 {
424 type Interrupt = interrupt::UARTE0_UART0;
425}
426
427#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
428impl Instance for pac::UARTE1 {
429 type Interrupt = interrupt::UARTE1;
430}
431
432pub trait TimerInstance:
433 Deref<Target = pac::timer0::RegisterBlock> + sealed::TimerInstance
434{
435}
436impl TimerInstance for crate::pac::TIMER0 {}
437impl TimerInstance for crate::pac::TIMER1 {}
438impl TimerInstance for crate::pac::TIMER2 {}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 67ff9dc31..042050d2f 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -40,17 +40,6 @@ pub use nrf52833_pac as pac;
40#[cfg(feature = "52840")] 40#[cfg(feature = "52840")]
41pub use nrf52840_pac as pac; 41pub use nrf52840_pac as pac;
42 42
43#[cfg(feature = "52810")]
44pub use nrf52810_hal as hal;
45#[cfg(feature = "52811")]
46pub use nrf52811_hal as hal;
47#[cfg(feature = "52832")]
48pub use nrf52832_hal as hal;
49#[cfg(feature = "52833")]
50pub use nrf52833_hal as hal;
51#[cfg(feature = "52840")]
52pub use nrf52840_hal as hal;
53
54/// Length of Nordic EasyDMA differs for MCUs 43/// Length of Nordic EasyDMA differs for MCUs
55#[cfg(any( 44#[cfg(any(
56 feature = "52810", 45 feature = "52810",