nrf52_hal_common/uarte.rs
1//! HAL interface to the UARTE peripheral
2//!
3//! See product specification:
4//!
5//! - nrf52832: Section 35
6//! - nrf52840: Section 6.34
7use core::ops::Deref;
8use core::sync::atomic::{compiler_fence, Ordering::SeqCst};
9use core::fmt;
10
11use crate::target::{
12 uarte0,
13 UARTE0,
14};
15
16use crate::target_constants::EASY_DMA_SIZE;
17use crate::prelude::*;
18use crate::gpio::{
19 Pin,
20 Output,
21 PushPull,
22 Input,
23 Floating,
24};
25use crate::timer::Timer;
26
27// Re-export SVD variants to allow user to directly set values
28pub use crate::target::uarte0::{
29 baudrate::BAUDRATEW as Baudrate,
30 config::PARITYW as Parity,
31};
32
33pub trait UarteExt: Deref<Target = uarte0::RegisterBlock> + Sized {
34 fn constrain(self, pins: Pins, parity: Parity, baudrate: Baudrate) -> Uarte<Self>;
35}
36
37impl UarteExt for UARTE0 {
38 fn constrain(self, pins: Pins, parity: Parity, baudrate: Baudrate) -> Uarte<Self> {
39 Uarte::new(self, pins, parity, baudrate)
40 }
41}
42
43/// Interface to a UARTE instance
44///
45/// This is a very basic interface that comes with the following limitations:
46/// - The UARTE instances share the same address space with instances of UART.
47/// You need to make sure that conflicting instances
48/// are disabled before using `Uarte`. See product specification:
49/// - nrf52832: Section 15.2
50/// - nrf52840: Section 6.1.2
51pub struct Uarte<T>(T);
52
53impl<T> Uarte<T> where T: UarteExt {
54 pub fn new(uarte: T, mut pins: Pins, parity: Parity, baudrate: Baudrate) -> Self {
55 // Select pins
56 uarte.psel.rxd.write(|w| {
57 let w = unsafe { w.pin().bits(pins.rxd.pin) };
58 #[cfg(feature = "52840")]
59 let w = w.port().bit(pins.rxd.port);
60 w.connect().connected()
61 });
62 pins.txd.set_high();
63 uarte.psel.txd.write(|w| {
64 let w = unsafe { w.pin().bits(pins.txd.pin) };
65 #[cfg(feature = "52840")]
66 let w = w.port().bit(pins.txd.port);
67 w.connect().connected()
68 });
69
70 // Optional pins
71 uarte.psel.cts.write(|w| {
72 if let Some(ref pin) = pins.cts {
73 let w = unsafe { w.pin().bits(pin.pin) };
74 #[cfg(feature = "52840")]
75 let w = w.port().bit(pin.port);
76 w.connect().connected()
77 } else {
78 w.connect().disconnected()
79 }
80 });
81
82 uarte.psel.rts.write(|w| {
83 if let Some(ref pin) = pins.rts {
84 let w = unsafe { w.pin().bits(pin.pin) };
85 #[cfg(feature = "52840")]
86 let w = w.port().bit(pin.port);
87 w.connect().connected()
88 } else {
89 w.connect().disconnected()
90 }
91 });
92
93 // Enable UARTE instance
94 uarte.enable.write(|w|
95 w.enable().enabled()
96 );
97
98 // Configure
99 let hardware_flow_control = pins.rts.is_some() && pins.cts.is_some();
100 uarte.config.write(|w|
101 w.hwfc().bit(hardware_flow_control)
102 .parity().variant(parity)
103 );
104
105 // Configure frequency
106 uarte.baudrate.write(|w|
107 w.baudrate().variant(baudrate)
108 );
109
110 Uarte(uarte)
111 }
112
113 /// Write via UARTE
114 ///
115 /// This method uses transmits all bytes in `tx_buffer`
116 ///
117 /// The buffer must have a length of at most 255 bytes on the nRF52832
118 /// and at most 65535 bytes on the nRF52840.
119 pub fn write(&mut self,
120 tx_buffer : &[u8],
121 )
122 -> Result<(), Error>
123 {
124 if tx_buffer.len() > EASY_DMA_SIZE {
125 return Err(Error::TxBufferTooLong);
126 }
127
128 // Conservative compiler fence to prevent optimizations that do not
129 // take in to account actions by DMA. The fence has been placed here,
130 // before any DMA action has started
131 compiler_fence(SeqCst);
132
133 // Set up the DMA write
134 self.0.txd.ptr.write(|w|
135 // We're giving the register a pointer to the stack. Since we're
136 // waiting for the UARTE transaction to end before this stack pointer
137 // becomes invalid, there's nothing wrong here.
138 //
139 // The PTR field is a full 32 bits wide and accepts the full range
140 // of values.
141 unsafe { w.ptr().bits(tx_buffer.as_ptr() as u32) }
142 );
143 self.0.txd.maxcnt.write(|w|
144 // We're giving it the length of the buffer, so no danger of
145 // accessing invalid memory. We have verified that the length of the
146 // buffer fits in an `u8`, so the cast to `u8` is also fine.
147 //
148 // The MAXCNT field is 8 bits wide and accepts the full range of
149 // values.
150 unsafe { w.maxcnt().bits(tx_buffer.len() as _) });
151
152 // Start UARTE Transmit transaction
153 self.0.tasks_starttx.write(|w|
154 // `1` is a valid value to write to task registers.
155 unsafe { w.bits(1) });
156
157 // Wait for transmission to end
158 while self.0.events_endtx.read().bits() == 0 {}
159
160 // Reset the event, otherwise it will always read `1` from now on.
161 self.0.events_endtx.write(|w| w);
162
163 // Conservative compiler fence to prevent optimizations that do not
164 // take in to account actions by DMA. The fence has been placed here,
165 // after all possible DMA actions have completed
166 compiler_fence(SeqCst);
167
168 if self.0.txd.amount.read().bits() != tx_buffer.len() as u32 {
169 return Err(Error::Transmit);
170 }
171
172 Ok(())
173 }
174
175 /// Read via UARTE
176 ///
177 /// This method fills all bytes in `rx_buffer`, and blocks
178 /// until the buffer is full.
179 ///
180 /// The buffer must have a length of at most 255 bytes
181 pub fn read(&mut self,
182 rx_buffer : &mut [u8],
183 )
184 -> Result<(), Error>
185 {
186 self.start_read(rx_buffer)?;
187
188 // Wait for transmission to end
189 while self.0.events_endrx.read().bits() == 0 {}
190
191 self.finalize_read();
192
193 if self.0.rxd.amount.read().bits() != rx_buffer.len() as u32 {
194 return Err(Error::Receive);
195 }
196
197 Ok(())
198 }
199
200 /// Read via UARTE
201 ///
202 /// This method fills all bytes in `rx_buffer`, and blocks
203 /// until the buffer is full or the timeout expires, whichever
204 /// comes first.
205 ///
206 /// If the timeout occurs, an `Error::Timeout(n)` will be returned,
207 /// where `n` is the number of bytes read successfully.
208 ///
209 /// This method assumes the interrupt for the given timer is NOT enabled,
210 /// and in cases where a timeout does NOT occur, the timer will be left running
211 /// until completion.
212 ///
213 /// The buffer must have a length of at most 255 bytes
214 pub fn read_timeout<I>(
215 &mut self,
216 rx_buffer: &mut [u8],
217 timer: &mut Timer<I>,
218 cycles: u32
219 ) -> Result<(), Error> where I: TimerExt
220 {
221 // Start the read
222 self.start_read(rx_buffer)?;
223
224 // Start the timeout timer
225 timer.start(cycles);
226
227 // Wait for transmission to end
228 let mut event_complete = false;
229 let mut timeout_occured = false;
230
231 loop {
232 event_complete |= self.0.events_endrx.read().bits() != 0;
233 timeout_occured |= timer.wait().is_ok();
234 if event_complete || timeout_occured {
235 break;
236 }
237 }
238
239 if !event_complete {
240 // Cancel the reception if it did not complete until now
241 self.cancel_read();
242 }
243
244 // Cleanup, even in the error case
245 self.finalize_read();
246
247 let bytes_read = self.0.rxd.amount.read().bits() as usize;
248
249 if timeout_occured && !event_complete {
250 return Err(Error::Timeout(bytes_read));
251 }
252
253 if bytes_read != rx_buffer.len() as usize {
254 return Err(Error::Receive);
255 }
256
257 Ok(())
258 }
259
260 /// Start a UARTE read transaction by setting the control
261 /// values and triggering a read task
262 fn start_read(&mut self, rx_buffer: &mut [u8]) -> Result<(), Error> {
263 // This is overly restrictive. See (similar SPIM issue):
264 // https://github.com/nrf-rs/nrf52/issues/17
265 if rx_buffer.len() > u8::max_value() as usize {
266 return Err(Error::TxBufferTooLong);
267 }
268
269 // Conservative compiler fence to prevent optimizations that do not
270 // take in to account actions by DMA. The fence has been placed here,
271 // before any DMA action has started
272 compiler_fence(SeqCst);
273
274 // Set up the DMA read
275 self.0.rxd.ptr.write(|w|
276 // We're giving the register a pointer to the stack. Since we're
277 // waiting for the UARTE transaction to end before this stack pointer
278 // becomes invalid, there's nothing wrong here.
279 //
280 // The PTR field is a full 32 bits wide and accepts the full range
281 // of values.
282 unsafe { w.ptr().bits(rx_buffer.as_ptr() as u32) }
283 );
284 self.0.rxd.maxcnt.write(|w|
285 // We're giving it the length of the buffer, so no danger of
286 // accessing invalid memory. We have verified that the length of the
287 // buffer fits in an `u8`, so the cast to `u8` is also fine.
288 //
289 // The MAXCNT field is at least 8 bits wide and accepts the full
290 // range of values.
291 unsafe { w.maxcnt().bits(rx_buffer.len() as _) });
292
293 // Start UARTE Receive transaction
294 self.0.tasks_startrx.write(|w|
295 // `1` is a valid value to write to task registers.
296 unsafe { w.bits(1) });
297
298 Ok(())
299 }
300
301 /// Finalize a UARTE read transaction by clearing the event
302 fn finalize_read(&mut self) {
303 // Reset the event, otherwise it will always read `1` from now on.
304 self.0.events_endrx.write(|w| w);
305
306 // Conservative compiler fence to prevent optimizations that do not
307 // take in to account actions by DMA. The fence has been placed here,
308 // after all possible DMA actions have completed
309 compiler_fence(SeqCst);
310 }
311
312 /// Stop an unfinished UART read transaction and flush FIFO to DMA buffer
313 fn cancel_read(&mut self) {
314 // Stop reception
315 self.0.tasks_stoprx.write(|w|
316 unsafe { w.bits(1) });
317
318 // Wait for the reception to have stopped
319 while self.0.events_rxto.read().bits() == 0 {}
320
321 // Reset the event flag
322 self.0.events_rxto.write(|w| w);
323
324 // Ask UART to flush FIFO to DMA buffer
325 self.0.tasks_flushrx.write(|w|
326 unsafe { w.bits(1) });
327
328 // Wait for the flush to complete.
329 while self.0.events_endrx.read().bits() == 0 {}
330
331 // The event flag itself is later reset by `finalize_read`.
332 }
333
334 /// Return the raw interface to the underlying UARTE peripheral
335 pub fn free(self) -> T {
336 self.0
337 }
338}
339
340impl<T> fmt::Write for Uarte<T> where T: UarteExt {
341 fn write_str(&mut self, s: &str) -> fmt::Result {
342 // Copy all data into an on-stack buffer so we never try to EasyDMA from
343 // flash
344 let buf = &mut [0; 16][..];
345 for block in s.as_bytes().chunks(16) {
346 buf[..block.len()].copy_from_slice(block);
347 self.write(&buf[..block.len()]).map_err(|_| fmt::Error)?;
348 }
349
350 Ok(())
351 }
352}
353
354pub struct Pins {
355 pub rxd: Pin<Input<Floating>>,
356 pub txd: Pin<Output<PushPull>>,
357 pub cts: Option<Pin<Input<Floating>>>,
358 pub rts: Option<Pin<Output<PushPull>>>,
359}
360
361
362#[derive(Debug)]
363pub enum Error {
364 TxBufferTooLong,
365 RxBufferTooLong,
366 Transmit,
367 Receive,
368 Timeout(usize),
369}