Skip to content

Commit a9deba8

Browse files
committed
Also release owned Pins with Usart::free()
1 parent 56cbdac commit a9deba8

File tree

1 file changed

+28
-25
lines changed

1 file changed

+28
-25
lines changed

nrf-hal-common/src/uarte.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
3636
/// are disabled before using `Uarte`. See product specification:
3737
/// - nrf52832: Section 15.2
3838
/// - nrf52840: Section 6.1.2
39-
pub struct Uarte<T>(T);
39+
pub struct Uarte<T> {
40+
uarte: T,
41+
pins: Pins,
42+
}
4043

4144
impl<T> Uarte<T>
4245
where
@@ -93,7 +96,7 @@ where
9396
// Configure frequency.
9497
uarte.baudrate.write(|w| w.baudrate().variant(baudrate));
9598

96-
Uarte(uarte)
99+
Uarte { uarte, pins }
97100
}
98101

99102
/// Write via UARTE.
@@ -116,19 +119,19 @@ where
116119
compiler_fence(SeqCst);
117120

118121
// Reset the events.
119-
self.0.events_endtx.reset();
120-
self.0.events_txstopped.reset();
122+
self.uarte.events_endtx.reset();
123+
self.uarte.events_txstopped.reset();
121124

122125
// Set up the DMA write.
123-
self.0.txd.ptr.write(|w|
126+
self.uarte.txd.ptr.write(|w|
124127
// We're giving the register a pointer to the stack. Since we're
125128
// waiting for the UARTE transaction to end before this stack pointer
126129
// becomes invalid, there's nothing wrong here.
127130
//
128131
// The PTR field is a full 32 bits wide and accepts the full range
129132
// of values.
130133
unsafe { w.ptr().bits(tx_buffer.as_ptr() as u32) });
131-
self.0.txd.maxcnt.write(|w|
134+
self.uarte.txd.maxcnt.write(|w|
132135
// We're giving it the length of the buffer, so no danger of
133136
// accessing invalid memory. We have verified that the length of the
134137
// buffer fits in an `u8`, so the cast to `u8` is also fine.
@@ -138,16 +141,16 @@ where
138141
unsafe { w.maxcnt().bits(tx_buffer.len() as _) });
139142

140143
// Start UARTE Transmit transaction.
141-
self.0.tasks_starttx.write(|w|
144+
self.uarte.tasks_starttx.write(|w|
142145
// `1` is a valid value to write to task registers.
143146
unsafe { w.bits(1) });
144147

145148
// Wait for transmission to end.
146149
let mut endtx;
147150
let mut txstopped;
148151
loop {
149-
endtx = self.0.events_endtx.read().bits() != 0;
150-
txstopped = self.0.events_txstopped.read().bits() != 0;
152+
endtx = self.uarte.events_endtx.read().bits() != 0;
153+
txstopped = self.uarte.events_txstopped.read().bits() != 0;
151154
if endtx || txstopped {
152155
break;
153156
}
@@ -164,7 +167,7 @@ where
164167

165168
// Lower power consumption by disabling the transmitter once we're
166169
// finished.
167-
self.0.tasks_stoptx.write(|w|
170+
self.uarte.tasks_stoptx.write(|w|
168171
// `1` is a valid value to write to task registers.
169172
unsafe { w.bits(1) });
170173

@@ -181,11 +184,11 @@ where
181184
self.start_read(rx_buffer)?;
182185

183186
// Wait for transmission to end.
184-
while self.0.events_endrx.read().bits() == 0 {}
187+
while self.uarte.events_endrx.read().bits() == 0 {}
185188

186189
self.finalize_read();
187190

188-
if self.0.rxd.amount.read().bits() != rx_buffer.len() as u32 {
191+
if self.uarte.rxd.amount.read().bits() != rx_buffer.len() as u32 {
189192
return Err(Error::Receive);
190193
}
191194

@@ -226,7 +229,7 @@ where
226229
let mut timeout_occured = false;
227230

228231
loop {
229-
event_complete |= self.0.events_endrx.read().bits() != 0;
232+
event_complete |= self.uarte.events_endrx.read().bits() != 0;
230233
timeout_occured |= timer.wait().is_ok();
231234
if event_complete || timeout_occured {
232235
break;
@@ -241,7 +244,7 @@ where
241244
// Cleanup, even in the error case.
242245
self.finalize_read();
243246

244-
let bytes_read = self.0.rxd.amount.read().bits() as usize;
247+
let bytes_read = self.uarte.rxd.amount.read().bits() as usize;
245248

246249
if timeout_occured && !event_complete {
247250
return Err(Error::Timeout(bytes_read));
@@ -272,15 +275,15 @@ where
272275
compiler_fence(SeqCst);
273276

274277
// Set up the DMA read
275-
self.0.rxd.ptr.write(|w|
278+
self.uarte.rxd.ptr.write(|w|
276279
// We're giving the register a pointer to the stack. Since we're
277280
// waiting for the UARTE transaction to end before this stack pointer
278281
// becomes invalid, there's nothing wrong here.
279282
//
280283
// The PTR field is a full 32 bits wide and accepts the full range
281284
// of values.
282285
unsafe { w.ptr().bits(rx_buffer.as_ptr() as u32) });
283-
self.0.rxd.maxcnt.write(|w|
286+
self.uarte.rxd.maxcnt.write(|w|
284287
// We're giving it the length of the buffer, so no danger of
285288
// accessing invalid memory. We have verified that the length of the
286289
// buffer fits in an `u8`, so the cast to `u8` is also fine.
@@ -290,7 +293,7 @@ where
290293
unsafe { w.maxcnt().bits(rx_buffer.len() as _) });
291294

292295
// Start UARTE Receive transaction.
293-
self.0.tasks_startrx.write(|w|
296+
self.uarte.tasks_startrx.write(|w|
294297
// `1` is a valid value to write to task registers.
295298
unsafe { w.bits(1) });
296299

@@ -300,7 +303,7 @@ where
300303
/// Finalize a UARTE read transaction by clearing the event.
301304
fn finalize_read(&mut self) {
302305
// Reset the event, otherwise it will always read `1` from now on.
303-
self.0.events_endrx.write(|w| w);
306+
self.uarte.events_endrx.write(|w| w);
304307

305308
// Conservative compiler fence to prevent optimizations that do not
306309
// take in to account actions by DMA. The fence has been placed here,
@@ -311,26 +314,26 @@ where
311314
/// Stop an unfinished UART read transaction and flush FIFO to DMA buffer.
312315
fn cancel_read(&mut self) {
313316
// Stop reception.
314-
self.0.tasks_stoprx.write(|w| unsafe { w.bits(1) });
317+
self.uarte.tasks_stoprx.write(|w| unsafe { w.bits(1) });
315318

316319
// Wait for the reception to have stopped.
317-
while self.0.events_rxto.read().bits() == 0 {}
320+
while self.uarte.events_rxto.read().bits() == 0 {}
318321

319322
// Reset the event flag.
320-
self.0.events_rxto.write(|w| w);
323+
self.uarte.events_rxto.write(|w| w);
321324

322325
// Ask UART to flush FIFO to DMA buffer.
323-
self.0.tasks_flushrx.write(|w| unsafe { w.bits(1) });
326+
self.uarte.tasks_flushrx.write(|w| unsafe { w.bits(1) });
324327

325328
// Wait for the flush to complete.
326-
while self.0.events_endrx.read().bits() == 0 {}
329+
while self.uarte.events_endrx.read().bits() == 0 {}
327330

328331
// The event flag itself is later reset by `finalize_read`.
329332
}
330333

331334
/// Return the raw interface to the underlying UARTE peripheral.
332-
pub fn free(self) -> T {
333-
self.0
335+
pub fn free(self) -> (T, Pins) {
336+
(self.uarte, self.pins)
334337
}
335338
}
336339

0 commit comments

Comments
 (0)