Skip to content

Commit d9259f9

Browse files
committed
Reconstruct Pins from UARTE peripheral registers
1 parent a9deba8 commit d9259f9

File tree

2 files changed

+75
-29
lines changed

2 files changed

+75
-29
lines changed

nrf-hal-common/src/gpio.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ impl Port {
5151
Port::Port1 => true,
5252
}
5353
}
54+
55+
#[cfg(any(feature = "52833", feature = "52840"))]
56+
pub(crate) fn from_bit(bit: bool) -> Port {
57+
if bit {
58+
Port::Port1
59+
} else {
60+
Port::Port0
61+
}
62+
}
5463
}
5564

5665
// ===============================================================
@@ -81,7 +90,7 @@ use crate::hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
8190
use void::Void;
8291

8392
impl<MODE> Pin<MODE> {
84-
fn new(port: Port, pin: u8) -> Self {
93+
pub(crate) fn new(port: Port, pin: u8) -> Self {
8594
let port_bits = match port {
8695
Port::Port0 => 0x00,
8796
#[cfg(any(feature = "52833", feature = "52840"))]

nrf-hal-common/src/uarte.rs

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::pac::{uarte0_ns as uarte0, UARTE0_NS as UARTE0, UARTE1_NS as UARTE1};
1919
#[cfg(not(feature = "9160"))]
2020
use crate::pac::{uarte0, UARTE0};
2121

22-
use crate::gpio::{Floating, Input, Output, Pin, PushPull};
22+
use crate::gpio::{Floating, Input, Output, Pin, Port, PushPull};
2323
use crate::prelude::*;
2424
use crate::slice_in_ram_or;
2525
use crate::target_constants::EASY_DMA_SIZE;
@@ -36,10 +36,7 @@ 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> {
40-
uarte: T,
41-
pins: Pins,
42-
}
39+
pub struct Uarte<T>(T);
4340

4441
impl<T> Uarte<T>
4542
where
@@ -96,7 +93,7 @@ where
9693
// Configure frequency.
9794
uarte.baudrate.write(|w| w.baudrate().variant(baudrate));
9895

99-
Uarte { uarte, pins }
96+
Uarte(uarte)
10097
}
10198

10299
/// Write via UARTE.
@@ -119,19 +116,19 @@ where
119116
compiler_fence(SeqCst);
120117

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

125122
// Set up the DMA write.
126-
self.uarte.txd.ptr.write(|w|
123+
self.0.txd.ptr.write(|w|
127124
// We're giving the register a pointer to the stack. Since we're
128125
// waiting for the UARTE transaction to end before this stack pointer
129126
// becomes invalid, there's nothing wrong here.
130127
//
131128
// The PTR field is a full 32 bits wide and accepts the full range
132129
// of values.
133130
unsafe { w.ptr().bits(tx_buffer.as_ptr() as u32) });
134-
self.uarte.txd.maxcnt.write(|w|
131+
self.0.txd.maxcnt.write(|w|
135132
// We're giving it the length of the buffer, so no danger of
136133
// accessing invalid memory. We have verified that the length of the
137134
// buffer fits in an `u8`, so the cast to `u8` is also fine.
@@ -141,16 +138,16 @@ where
141138
unsafe { w.maxcnt().bits(tx_buffer.len() as _) });
142139

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

148145
// Wait for transmission to end.
149146
let mut endtx;
150147
let mut txstopped;
151148
loop {
152-
endtx = self.uarte.events_endtx.read().bits() != 0;
153-
txstopped = self.uarte.events_txstopped.read().bits() != 0;
149+
endtx = self.0.events_endtx.read().bits() != 0;
150+
txstopped = self.0.events_txstopped.read().bits() != 0;
154151
if endtx || txstopped {
155152
break;
156153
}
@@ -167,7 +164,7 @@ where
167164

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

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

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

189186
self.finalize_read();
190187

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

@@ -229,7 +226,7 @@ where
229226
let mut timeout_occured = false;
230227

231228
loop {
232-
event_complete |= self.uarte.events_endrx.read().bits() != 0;
229+
event_complete |= self.0.events_endrx.read().bits() != 0;
233230
timeout_occured |= timer.wait().is_ok();
234231
if event_complete || timeout_occured {
235232
break;
@@ -244,7 +241,7 @@ where
244241
// Cleanup, even in the error case.
245242
self.finalize_read();
246243

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

249246
if timeout_occured && !event_complete {
250247
return Err(Error::Timeout(bytes_read));
@@ -275,15 +272,15 @@ where
275272
compiler_fence(SeqCst);
276273

277274
// Set up the DMA read
278-
self.uarte.rxd.ptr.write(|w|
275+
self.0.rxd.ptr.write(|w|
279276
// We're giving the register a pointer to the stack. Since we're
280277
// waiting for the UARTE transaction to end before this stack pointer
281278
// becomes invalid, there's nothing wrong here.
282279
//
283280
// The PTR field is a full 32 bits wide and accepts the full range
284281
// of values.
285282
unsafe { w.ptr().bits(rx_buffer.as_ptr() as u32) });
286-
self.uarte.rxd.maxcnt.write(|w|
283+
self.0.rxd.maxcnt.write(|w|
287284
// We're giving it the length of the buffer, so no danger of
288285
// accessing invalid memory. We have verified that the length of the
289286
// buffer fits in an `u8`, so the cast to `u8` is also fine.
@@ -293,7 +290,7 @@ where
293290
unsafe { w.maxcnt().bits(rx_buffer.len() as _) });
294291

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

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

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

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

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

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

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

331328
// The event flag itself is later reset by `finalize_read`.
332329
}
333330

334331
/// Return the raw interface to the underlying UARTE peripheral.
335332
pub fn free(self) -> (T, Pins) {
336-
(self.uarte, self.pins)
333+
let rxd = self.0.psel.rxd.read();
334+
let txd = self.0.psel.txd.read();
335+
let cts = self.0.psel.cts.read();
336+
let rts = self.0.psel.rts.read();
337+
(
338+
self.0,
339+
Pins {
340+
#[cfg(any(feature = "52833", feature = "52840"))]
341+
rxd: Pin::new(Port::from_bit(rxd.port().bit()), rxd.pin().bits()),
342+
#[cfg(not(any(feature = "52833", feature = "52840")))]
343+
rxd: Pin::new(Port::Port0, rxd.pin().bits()),
344+
#[cfg(any(feature = "52833", feature = "52840"))]
345+
txd: Pin::new(Port::from_bit(txd.port().bit()), txd.pin().bits()),
346+
#[cfg(not(any(feature = "52833", feature = "52840")))]
347+
txd: Pin::new(Port::Port0, txd.pin().bits()),
348+
cts: if cts.connect().bit_is_set() {
349+
#[cfg(any(feature = "52833", feature = "52840"))]
350+
{
351+
Some(Pin::new(Port::from_bit(cts.port().bit()), cts.pin().bits()))
352+
}
353+
#[cfg(not(any(feature = "52833", feature = "52840")))]
354+
{
355+
Some(Pin::new(Port::Port0, cts.pin().bits()))
356+
}
357+
} else {
358+
None
359+
},
360+
rts: if rts.connect().bit_is_set() {
361+
#[cfg(any(feature = "52833", feature = "52840"))]
362+
{
363+
Some(Pin::new(Port::from_bit(rts.port().bit()), rts.pin().bits()))
364+
}
365+
#[cfg(not(any(feature = "52833", feature = "52840")))]
366+
{
367+
Some(Pin::new(Port::Port0, rts.pin().bits()))
368+
}
369+
} else {
370+
None
371+
},
372+
},
373+
)
337374
}
338375
}
339376

0 commit comments

Comments
 (0)