1use 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    Task [
84        ENABLE OFFSET(0) NUMBITS(1)
85    ],
86
87    Event [
89        READY OFFSET(0) NUMBITS(1)
90    ],
91
92    Shorts [
94        ENDRX_STARTRX OFFSET(5) NUMBITS(1),
96        ENDRX_STOPRX OFFSET(6) NUMBITS(1)
98    ],
99
100    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    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    Uart [
123        ENABLE OFFSET(0) NUMBITS(4) [
124            ON = 8,
125            OFF = 0
126        ]
127    ],
128
129    Psel [
131        PIN OFFSET(0) NUMBITS(6),
136        CONNECT OFFSET(31) NUMBITS(1)
138    ],
139
140    Baudrate [
142        BAUDRAUTE OFFSET(0) NUMBITS(32)
143    ],
144
145    Pointer [
147        POINTER OFFSET(0) NUMBITS(32)
148    ],
149
150    Counter [
152        COUNTER OFFSET(0) NUMBITS(8)
153    ],
154
155    Config [
157        HWFC OFFSET(0) NUMBITS(1),
158        PARITY OFFSET(1) NUMBITS(3)
159    ]
160];
161
162pub 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    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    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                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                self.registers.pselrts.write(Psel::CONNECT::SET);
226            },
227            |r| {
228                self.registers.pselrts.write(Psel::PIN.val(r.into()));
229            },
230        );
231
232        self.registers.event_endtx.write(Event::READY::CLEAR);
238
239        self.enable_uart();
240    }
241
242    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        let system_clock = 16000000u64; let scalar = 32u64;
257        let target_baud: u64 = baud_rate.into();
258
259        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    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    #[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            if rem == 0 {
314                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                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            self.registers.event_endrx.write(Event::READY::CLEAR);
338
339            let rx_bytes = self.registers.rxd_amount.get() as usize;
341
342            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                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                    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                    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                    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    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        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    pub fn tx_ready(&self) -> bool {
410        self.registers.event_endtx.is_set(Event::READY)
411    }
412
413    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    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        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        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        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        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(19200), Ok(0x004EA000));
576        assert_eq!(u.get_divider_for_baud(76800), Ok(0x013A9000));
580        assert_eq!(u.get_divider_for_baud(250000), Ok(0x04000000));
583        assert_eq!(u.get_divider_for_baud(1000000), Ok(0x10000000));
586        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}