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}