nrf52/
uart.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Universal asynchronous receiver/transmitter with EasyDMA (UARTE)
6//!
7//! Author
8//! -------------------
9//!
10//! * Author: Niklas Adolfsson <niklasadolfsson1@gmail.com>
11//! * Date: March 10 2018
12
13use core::cell::Cell;
14use core::cmp::min;
15use kernel::hil::uart;
16use kernel::utilities::cells::OptionalCell;
17use kernel::utilities::registers::interfaces::{Readable, Writeable};
18use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
19use kernel::utilities::StaticRef;
20use kernel::ErrorCode;
21use nrf5x::pinmux;
22
23const UARTE_MAX_BUFFER_SIZE: u32 = 0xff;
24
25static mut BYTE: u8 = 0;
26
27pub const UARTE0_BASE: StaticRef<UarteRegisters> =
28    unsafe { StaticRef::new(0x40002000 as *const UarteRegisters) };
29
30#[repr(C)]
31pub struct UarteRegisters {
32    task_startrx: WriteOnly<u32, Task::Register>,
33    task_stoprx: WriteOnly<u32, Task::Register>,
34    task_starttx: WriteOnly<u32, Task::Register>,
35    task_stoptx: WriteOnly<u32, Task::Register>,
36    _reserved1: [u32; 7],
37    task_flush_rx: WriteOnly<u32, Task::Register>,
38    _reserved2: [u32; 52],
39    event_cts: ReadWrite<u32, Event::Register>,
40    event_ncts: ReadWrite<u32, Event::Register>,
41    _reserved3: [u32; 2],
42    event_endrx: ReadWrite<u32, Event::Register>,
43    _reserved4: [u32; 3],
44    event_endtx: ReadWrite<u32, Event::Register>,
45    event_error: ReadWrite<u32, Event::Register>,
46    _reserved6: [u32; 7],
47    event_rxto: ReadWrite<u32, Event::Register>,
48    _reserved7: [u32; 1],
49    event_rxstarted: ReadWrite<u32, Event::Register>,
50    event_txstarted: ReadWrite<u32, Event::Register>,
51    _reserved8: [u32; 1],
52    event_txstopped: ReadWrite<u32, Event::Register>,
53    _reserved9: [u32; 41],
54    shorts: ReadWrite<u32, Shorts::Register>,
55    _reserved10: [u32; 64],
56    intenset: ReadWrite<u32, Interrupt::Register>,
57    intenclr: ReadWrite<u32, Interrupt::Register>,
58    _reserved11: [u32; 93],
59    errorsrc: ReadWrite<u32, ErrorSrc::Register>,
60    _reserved12: [u32; 31],
61    enable: ReadWrite<u32, Uart::Register>,
62    _reserved13: [u32; 1],
63    pselrts: ReadWrite<u32, Psel::Register>,
64    pseltxd: ReadWrite<u32, Psel::Register>,
65    pselcts: ReadWrite<u32, Psel::Register>,
66    pselrxd: ReadWrite<u32, Psel::Register>,
67    _reserved14: [u32; 3],
68    baudrate: ReadWrite<u32, Baudrate::Register>,
69    _reserved15: [u32; 3],
70    rxd_ptr: ReadWrite<u32, Pointer::Register>,
71    rxd_maxcnt: ReadWrite<u32, Counter::Register>,
72    rxd_amount: ReadOnly<u32, Counter::Register>,
73    _reserved16: [u32; 1],
74    txd_ptr: ReadWrite<u32, Pointer::Register>,
75    txd_maxcnt: ReadWrite<u32, Counter::Register>,
76    txd_amount: ReadOnly<u32, Counter::Register>,
77    _reserved17: [u32; 7],
78    config: ReadWrite<u32, Config::Register>,
79}
80
81register_bitfields! [u32,
82    /// Start task
83    Task [
84        ENABLE OFFSET(0) NUMBITS(1)
85    ],
86
87    /// Read event
88    Event [
89        READY OFFSET(0) NUMBITS(1)
90    ],
91
92    /// Shortcuts
93    Shorts [
94        // Shortcut between ENDRX and STARTRX
95        ENDRX_STARTRX OFFSET(5) NUMBITS(1),
96        // Shortcut between ENDRX and STOPRX
97        ENDRX_STOPRX OFFSET(6) NUMBITS(1)
98    ],
99
100    /// UART Interrupts
101    Interrupt [
102        CTS OFFSET(0) NUMBITS(1),
103        NCTS OFFSET(1) NUMBITS(1),
104        ENDRX OFFSET(4) NUMBITS(1),
105        ENDTX OFFSET(8) NUMBITS(1),
106        ERROR OFFSET(9) NUMBITS(1),
107        RXTO OFFSET(17) NUMBITS(1),
108        RXSTARTED OFFSET(19) NUMBITS(1),
109        TXSTARTED OFFSET(20) NUMBITS(1),
110        TXSTOPPED OFFSET(22) NUMBITS(1)
111    ],
112
113    /// UART Errors
114    ErrorSrc [
115        OVERRUN OFFSET(0) NUMBITS(1),
116        PARITY OFFSET(1) NUMBITS(1),
117        FRAMING OFFSET(2) NUMBITS(1),
118        BREAK OFFSET(3) NUMBITS(1)
119    ],
120
121    /// Enable UART
122    Uart [
123        ENABLE OFFSET(0) NUMBITS(4) [
124            ON = 8,
125            OFF = 0
126        ]
127    ],
128
129    /// Pin select
130    Psel [
131        // Pin number. MSB is actually the port indicator, but since we number
132        // pins sequentially the binary representation of the pin number has
133        // the port bit set correctly. So, for simplicity we just treat the
134        // pin number as a 6 bit field.
135        PIN OFFSET(0) NUMBITS(6),
136        // Connect/Disconnect
137        CONNECT OFFSET(31) NUMBITS(1)
138    ],
139
140    /// Baudrate
141    Baudrate [
142        BAUDRAUTE OFFSET(0) NUMBITS(32)
143    ],
144
145    /// DMA pointer
146    Pointer [
147        POINTER OFFSET(0) NUMBITS(32)
148    ],
149
150    /// Counter value
151    Counter [
152        COUNTER OFFSET(0) NUMBITS(8)
153    ],
154
155    /// Configuration of parity and flow control
156    Config [
157        HWFC OFFSET(0) NUMBITS(1),
158        PARITY OFFSET(1) NUMBITS(3)
159    ]
160];
161
162/// UARTE
163// It should never be instanced outside this module but because a static mutable reference to it
164// is exported outside this module it must be `pub`
165pub struct Uarte<'a> {
166    registers: StaticRef<UarteRegisters>,
167    tx_client: OptionalCell<&'a dyn uart::TransmitClient>,
168    tx_buffer: kernel::utilities::cells::TakeCell<'static, [u8]>,
169    tx_len: Cell<usize>,
170    tx_remaining_bytes: Cell<usize>,
171    rx_client: OptionalCell<&'a dyn uart::ReceiveClient>,
172    rx_buffer: kernel::utilities::cells::TakeCell<'static, [u8]>,
173    rx_remaining_bytes: Cell<usize>,
174    rx_abort_in_progress: Cell<bool>,
175    offset: Cell<usize>,
176}
177
178#[derive(Copy, Clone)]
179pub struct UARTParams {
180    pub baud_rate: u32,
181}
182
183impl<'a> Uarte<'a> {
184    /// Constructor
185    // This should only be constructed once
186    pub const fn new(regs: StaticRef<UarteRegisters>) -> Uarte<'a> {
187        Uarte {
188            registers: regs,
189            tx_client: OptionalCell::empty(),
190            tx_buffer: kernel::utilities::cells::TakeCell::empty(),
191            tx_len: Cell::new(0),
192            tx_remaining_bytes: Cell::new(0),
193            rx_client: OptionalCell::empty(),
194            rx_buffer: kernel::utilities::cells::TakeCell::empty(),
195            rx_remaining_bytes: Cell::new(0),
196            rx_abort_in_progress: Cell::new(false),
197            offset: Cell::new(0),
198        }
199    }
200
201    /// Configure which pins the UART should use for txd, rxd, cts and rts
202    pub fn initialize(
203        &self,
204        txd: pinmux::Pinmux,
205        rxd: pinmux::Pinmux,
206        cts: Option<pinmux::Pinmux>,
207        rts: Option<pinmux::Pinmux>,
208    ) {
209        self.registers.pseltxd.write(Psel::PIN.val(txd.into()));
210        self.registers.pselrxd.write(Psel::PIN.val(rxd.into()));
211        cts.map_or_else(
212            || {
213                // If no CTS pin is provided, then we need to mark it as
214                // disconnected in the register.
215                self.registers.pselcts.write(Psel::CONNECT::SET);
216            },
217            |c| {
218                self.registers.pselcts.write(Psel::PIN.val(c.into()));
219            },
220        );
221        rts.map_or_else(
222            || {
223                // If no RTS pin is provided, then we need to mark it as
224                // disconnected in the register.
225                self.registers.pselrts.write(Psel::CONNECT::SET);
226            },
227            |r| {
228                self.registers.pselrts.write(Psel::PIN.val(r.into()));
229            },
230        );
231
232        // Make sure we clear the endtx interrupt since that is what we rely on
233        // to know when the DMA TX finishes. Normally, we clear this interrupt
234        // as we handle it, so this is not necessary. However, a bootloader (or
235        // some other startup code) may have setup TX interrupts, and there may
236        // be one pending. We clear it to be safe.
237        self.registers.event_endtx.write(Event::READY::CLEAR);
238
239        self.enable_uart();
240    }
241
242    // The datasheet gives a non-exhaustive list of example settings for
243    // typical bauds. The register is actually just a simple clock divider,
244    // as explained and with implementation from:
245    // https://devzone.nordicsemi.com/f/nordic-q-a/43280/technical-question-regarding-uart-baud-rate-generator-baudrate-register-offset-0x524
246    //
247    // Technically only RX is limited to 1MBaud, can TX up to 8MBaud:
248    // https://devzone.nordicsemi.com/f/nordic-q-a/84204/framing-error-and-noisy-data-when-using-uarte-at-high-baud-rate
249    fn get_divider_for_baud(&self, baud_rate: u32) -> Result<u32, ErrorCode> {
250        if baud_rate > 1_000_000 || baud_rate < 1200 {
251            return Err(ErrorCode::INVAL);
252        }
253
254        // force 64 bit values for precision
255        let system_clock = 16000000u64; // TODO: Support dynamic clock
256        let scalar = 32u64;
257        let target_baud: u64 = baud_rate.into();
258
259        // n.b. bits 11-0 are ignored by hardware
260        let divider64 = (((target_baud << scalar) + (system_clock >> 1)) / system_clock) + 0x800;
261        let divider = (divider64 & 0xffff_f000) as u32;
262
263        Ok(divider)
264    }
265
266    fn set_baud_rate(&self, baud_rate: u32) -> Result<(), ErrorCode> {
267        let divider = self.get_divider_for_baud(baud_rate)?;
268        self.registers.baudrate.set(divider);
269
270        Ok(())
271    }
272
273    // Enable UART peripheral, this need to disabled for low power applications
274    fn enable_uart(&self) {
275        self.registers.enable.write(Uart::ENABLE::ON);
276    }
277
278    #[allow(dead_code)]
279    fn disable_uart(&self) {
280        self.registers.enable.write(Uart::ENABLE::OFF);
281    }
282
283    fn enable_rx_interrupts(&self) {
284        self.registers.intenset.write(Interrupt::ENDRX::SET);
285    }
286
287    fn enable_tx_interrupts(&self) {
288        self.registers.intenset.write(Interrupt::ENDTX::SET);
289    }
290
291    fn disable_rx_interrupts(&self) {
292        self.registers.intenclr.write(Interrupt::ENDRX::SET);
293    }
294
295    fn disable_tx_interrupts(&self) {
296        self.registers.intenclr.write(Interrupt::ENDTX::SET);
297    }
298
299    /// UART interrupt handler that listens for both tx_end and rx_end events
300    #[inline(never)]
301    pub fn handle_interrupt(&self) {
302        if self.tx_ready() {
303            self.disable_tx_interrupts();
304            self.registers.event_endtx.write(Event::READY::CLEAR);
305            let tx_bytes = self.registers.txd_amount.get() as usize;
306
307            let rem = match self.tx_remaining_bytes.get().checked_sub(tx_bytes) {
308                None => return,
309                Some(r) => r,
310            };
311
312            // All bytes have been transmitted
313            if rem == 0 {
314                // Signal client write done
315                self.tx_client.map(|client| {
316                    self.tx_buffer.take().map(|tx_buffer| {
317                        client.transmitted_buffer(tx_buffer, self.tx_len.get(), Ok(()));
318                    });
319                });
320            } else {
321                // Not all bytes have been transmitted then update offset and continue transmitting
322                self.offset.set(self.offset.get() + tx_bytes);
323                self.tx_remaining_bytes.set(rem);
324                self.set_tx_dma_pointer_to_buffer();
325                self.registers
326                    .txd_maxcnt
327                    .write(Counter::COUNTER.val(min(rem as u32, UARTE_MAX_BUFFER_SIZE)));
328                self.registers.task_starttx.write(Task::ENABLE::SET);
329                self.enable_tx_interrupts();
330            }
331        }
332
333        if self.rx_ready() {
334            self.disable_rx_interrupts();
335
336            // Clear the ENDRX event
337            self.registers.event_endrx.write(Event::READY::CLEAR);
338
339            // Get the number of bytes in the buffer that was received this time
340            let rx_bytes = self.registers.rxd_amount.get() as usize;
341
342            // Check if this ENDRX is due to an abort. If so, we want to
343            // do the receive callback immediately.
344            if self.rx_abort_in_progress.get() {
345                self.rx_abort_in_progress.set(false);
346                self.rx_client.map(|client| {
347                    self.rx_buffer.take().map(|rx_buffer| {
348                        client.received_buffer(
349                            rx_buffer,
350                            self.offset.get() + rx_bytes,
351                            Err(ErrorCode::CANCEL),
352                            uart::Error::None,
353                        );
354                    });
355                });
356            } else {
357                // In the normal case, we need to either pass call the callback
358                // or do another read to get more bytes.
359
360                // Update how many bytes we still need to receive and
361                // where we are storing in the buffer.
362                self.rx_remaining_bytes
363                    .set(self.rx_remaining_bytes.get().saturating_sub(rx_bytes));
364                self.offset.set(self.offset.get() + rx_bytes);
365
366                let rem = self.rx_remaining_bytes.get();
367                if rem == 0 {
368                    // Signal client that the read is done
369                    self.rx_client.map(|client| {
370                        self.rx_buffer.take().map(|rx_buffer| {
371                            client.received_buffer(
372                                rx_buffer,
373                                self.offset.get(),
374                                Ok(()),
375                                uart::Error::None,
376                            );
377                        });
378                    });
379                } else {
380                    // Setup how much we can read. We already made sure that
381                    // this will fit in the buffer.
382                    let to_read = core::cmp::min(rem, 255);
383                    self.registers
384                        .rxd_maxcnt
385                        .write(Counter::COUNTER.val(to_read as u32));
386
387                    // Actually do the receive.
388                    self.set_rx_dma_pointer_to_buffer();
389                    self.registers.task_startrx.write(Task::ENABLE::SET);
390                    self.enable_rx_interrupts();
391                }
392            }
393        }
394    }
395
396    /// Transmit one byte at the time and the client is responsible for polling
397    /// This is used by the panic handler
398    pub unsafe fn send_byte(&self, byte: u8) {
399        self.tx_remaining_bytes.set(1);
400        self.registers.event_endtx.write(Event::READY::CLEAR);
401        // precaution: copy value into variable with static lifetime
402        BYTE = byte;
403        self.registers.txd_ptr.set(core::ptr::addr_of!(BYTE) as u32);
404        self.registers.txd_maxcnt.write(Counter::COUNTER.val(1));
405        self.registers.task_starttx.write(Task::ENABLE::SET);
406    }
407
408    /// Check if the UART transmission is done
409    pub fn tx_ready(&self) -> bool {
410        self.registers.event_endtx.is_set(Event::READY)
411    }
412
413    /// Check if either the rx_buffer is full or the UART has timed out
414    pub fn rx_ready(&self) -> bool {
415        self.registers.event_endrx.is_set(Event::READY)
416    }
417
418    fn set_tx_dma_pointer_to_buffer(&self) {
419        self.tx_buffer.map(|tx_buffer| {
420            self.registers
421                .txd_ptr
422                .set(tx_buffer[self.offset.get()..].as_ptr() as u32);
423        });
424    }
425
426    fn set_rx_dma_pointer_to_buffer(&self) {
427        self.rx_buffer.map(|rx_buffer| {
428            self.registers
429                .rxd_ptr
430                .set(rx_buffer[self.offset.get()..].as_ptr() as u32);
431        });
432    }
433
434    // Helper function used by both transmit_word and transmit_buffer
435    fn setup_buffer_transmit(&self, buf: &'static mut [u8], tx_len: usize) {
436        self.tx_remaining_bytes.set(tx_len);
437        self.tx_len.set(tx_len);
438        self.offset.set(0);
439        self.tx_buffer.replace(buf);
440        self.set_tx_dma_pointer_to_buffer();
441
442        self.registers
443            .txd_maxcnt
444            .write(Counter::COUNTER.val(min(tx_len as u32, UARTE_MAX_BUFFER_SIZE)));
445        self.registers.task_starttx.write(Task::ENABLE::SET);
446
447        self.enable_tx_interrupts();
448    }
449}
450
451impl<'a> uart::Transmit<'a> for Uarte<'a> {
452    fn set_transmit_client(&self, client: &'a dyn uart::TransmitClient) {
453        self.tx_client.set(client);
454    }
455
456    fn transmit_buffer(
457        &self,
458        tx_data: &'static mut [u8],
459        tx_len: usize,
460    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
461        if tx_len == 0 || tx_len > tx_data.len() {
462            Err((ErrorCode::SIZE, tx_data))
463        } else if self.tx_buffer.is_some() {
464            Err((ErrorCode::BUSY, tx_data))
465        } else {
466            self.setup_buffer_transmit(tx_data, tx_len);
467            Ok(())
468        }
469    }
470
471    fn transmit_word(&self, _data: u32) -> Result<(), ErrorCode> {
472        Err(ErrorCode::FAIL)
473    }
474
475    fn transmit_abort(&self) -> Result<(), ErrorCode> {
476        Err(ErrorCode::FAIL)
477    }
478}
479
480impl uart::Configure for Uarte<'_> {
481    fn configure(&self, params: uart::Parameters) -> Result<(), ErrorCode> {
482        // These could probably be implemented, but are currently ignored, so
483        // throw an error.
484        if params.stop_bits != uart::StopBits::One {
485            return Err(ErrorCode::NOSUPPORT);
486        }
487        if params.parity != uart::Parity::None {
488            return Err(ErrorCode::NOSUPPORT);
489        }
490        if params.hw_flow_control {
491            return Err(ErrorCode::NOSUPPORT);
492        }
493
494        self.set_baud_rate(params.baud_rate)?;
495
496        Ok(())
497    }
498}
499
500impl<'a> uart::Receive<'a> for Uarte<'a> {
501    fn set_receive_client(&self, client: &'a dyn uart::ReceiveClient) {
502        self.rx_client.set(client);
503    }
504
505    fn receive_buffer(
506        &self,
507        rx_buf: &'static mut [u8],
508        rx_len: usize,
509    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
510        if self.rx_buffer.is_some() {
511            return Err((ErrorCode::BUSY, rx_buf));
512        }
513        // truncate rx_len if necessary
514        let truncated_length = core::cmp::min(rx_len, rx_buf.len());
515
516        self.rx_remaining_bytes.set(truncated_length);
517        self.offset.set(0);
518        self.rx_buffer.replace(rx_buf);
519        self.set_rx_dma_pointer_to_buffer();
520
521        let truncated_uart_max_length = core::cmp::min(truncated_length, 255);
522
523        self.registers
524            .rxd_maxcnt
525            .write(Counter::COUNTER.val(truncated_uart_max_length as u32));
526        self.registers.task_stoprx.write(Task::ENABLE::SET);
527        self.registers.task_startrx.write(Task::ENABLE::SET);
528
529        self.enable_rx_interrupts();
530        Ok(())
531    }
532
533    fn receive_word(&self) -> Result<(), ErrorCode> {
534        Err(ErrorCode::FAIL)
535    }
536
537    fn receive_abort(&self) -> Result<(), ErrorCode> {
538        // Trigger the STOPRX event to cancel the current receive call.
539        if self.rx_buffer.is_none() {
540            Ok(())
541        } else {
542            self.rx_abort_in_progress.set(true);
543            self.registers.task_stoprx.write(Task::ENABLE::SET);
544            Err(ErrorCode::BUSY)
545        }
546    }
547}
548
549#[cfg(test)]
550mod tests {
551    use kernel::ErrorCode;
552
553    #[test]
554    fn baud_rate_divider_calculation() {
555        let u = super::Uarte::new(super::UARTE0_BASE);
556        assert_eq!(u.get_divider_for_baud(0), Err(ErrorCode::INVAL));
557        assert_eq!(u.get_divider_for_baud(4_000_000), Err(ErrorCode::INVAL));
558
559        // The constants below are the list from the Nordic technical documents.
560        //
561        // n.b., some datasheet constants do not match formula constants,
562        // so we skip those, see nordic forum thread for details:
563        // https://devzone.nordicsemi.com/f/nordic-q-a/84204/framing-error-and-noisy-data-when-using-uarte-at-high-baud-rate
564        //
565        // This is a *datasheet bug*, i.e., for a target baud of 115200, the
566        // datasheet divisor yields 115108 (-0.079% err) where direct
567        // computation of the divider yields 115203 (+0.002% err). Both work in
568        // practice, but the error here is an annoying and uncharacteristic
569        // Nordic quirk.
570        assert_eq!(u.get_divider_for_baud(1200), Ok(0x0004F000));
571        assert_eq!(u.get_divider_for_baud(2400), Ok(0x0009D000));
572        assert_eq!(u.get_divider_for_baud(4800), Ok(0x0013B000));
573        assert_eq!(u.get_divider_for_baud(9600), Ok(0x00275000));
574        //assert_eq!(u.get_divider_for_baud(14400), Ok(0x003AF000));
575        assert_eq!(u.get_divider_for_baud(19200), Ok(0x004EA000));
576        //assert_eq!(u.get_divider_for_baud(28800), Ok(0x0075C000));
577        //assert_eq!(u.get_divider_for_baud(38400), Ok(0x009D0000));
578        //assert_eq!(u.get_divider_for_baud(57600), Ok(0x00EB0000));
579        assert_eq!(u.get_divider_for_baud(76800), Ok(0x013A9000));
580        //assert_eq!(u.get_divider_for_baud(115200), Ok(0x01D60000));
581        //assert_eq!(u.get_divider_for_baud(230400), Ok(0x03B00000));
582        assert_eq!(u.get_divider_for_baud(250000), Ok(0x04000000));
583        //assert_eq!(u.get_divider_for_baud(460800), Ok(0x07400000));
584        //assert_eq!(u.get_divider_for_baud(921600), Ok(0x0F000000));
585        assert_eq!(u.get_divider_for_baud(1000000), Ok(0x10000000));
586        //
587        // For completeness of testing, we do verify that the calculation works
588        // as-expected to generate the empirically correct divisors.  (i.e.,
589        // these are not the datasheet constants, but are the correct divisors
590        // for the desired bauds):
591        assert_eq!(u.get_divider_for_baud(14400), Ok(0x003B0000));
592        assert_eq!(u.get_divider_for_baud(28800), Ok(0x0075F000));
593        assert_eq!(u.get_divider_for_baud(38400), Ok(0x009D5000));
594        assert_eq!(u.get_divider_for_baud(57600), Ok(0x00EBF000));
595        assert_eq!(u.get_divider_for_baud(115200), Ok(0x01D7E000));
596        assert_eq!(u.get_divider_for_baud(230400), Ok(0x03AFB000));
597        assert_eq!(u.get_divider_for_baud(460800), Ok(0x075F7000));
598        assert_eq!(u.get_divider_for_baud(921600), Ok(0x0EBEE000));
599    }
600}