sifive/
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//! UART driver.
6
7use core::cell::Cell;
8use kernel::utilities::registers::FieldValue;
9use kernel::ErrorCode;
10
11use crate::gpio;
12use kernel::hil;
13use kernel::utilities::cells::OptionalCell;
14use kernel::utilities::cells::TakeCell;
15use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
16use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
17use kernel::utilities::StaticRef;
18
19use kernel::deferred_call::{DeferredCall, DeferredCallClient};
20
21#[repr(C)]
22pub struct UartRegisters {
23    /// Transmit Data Register
24    txdata: ReadWrite<u32, txdata::Register>,
25    /// Receive Data Register
26    rxdata: ReadWrite<u32, rxdata::Register>,
27    /// Transmit Control Register
28    txctrl: ReadWrite<u32, txctrl::Register>,
29    /// Receive Control Register
30    rxctrl: ReadWrite<u32, rxctrl::Register>,
31    /// Interrupt Enable Register
32    ie: ReadWrite<u32, interrupt::Register>,
33    /// Interrupt Pending Register
34    ip: ReadOnly<u32, interrupt::Register>,
35    /// Baud Rate Divisor Register
36    div: ReadWrite<u32, div::Register>,
37}
38
39register_bitfields![u32,
40    txdata [
41        full OFFSET(31) NUMBITS(1) [],
42        data OFFSET(0) NUMBITS(8) []
43    ],
44    rxdata [
45        empty OFFSET(31) NUMBITS(1) [],
46        data OFFSET(0) NUMBITS(8) []
47    ],
48    txctrl [
49        txcnt OFFSET(16) NUMBITS(3) [],
50        nstop OFFSET(1) NUMBITS(1) [
51            OneStopBit = 0,
52            TwoStopBits = 1
53        ],
54        txen OFFSET(0) NUMBITS(1) []
55    ],
56    rxctrl [
57        counter OFFSET(16) NUMBITS(3) [],
58        enable OFFSET(0) NUMBITS(1) []
59    ],
60    interrupt [
61        rxwm OFFSET(1) NUMBITS(1) [],
62        txwm OFFSET(0) NUMBITS(1) []
63    ],
64    div [
65        div OFFSET(0) NUMBITS(16) []
66    ]
67];
68
69#[derive(Copy, Clone, PartialEq)]
70enum UARTStateTX {
71    Idle,
72    Transmitting,
73    AbortRequested,
74}
75
76#[derive(Copy, Clone, PartialEq)]
77enum UARTStateRX {
78    Idle,
79    Receiving,
80    AbortRequested,
81}
82
83pub struct Uart<'a> {
84    registers: StaticRef<UartRegisters>,
85    clock_frequency: u32,
86    stop_bits: Cell<hil::uart::StopBits>,
87
88    tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
89    rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
90
91    tx_buffer: TakeCell<'static, [u8]>,
92    tx_len: Cell<usize>,
93    tx_position: Cell<usize>,
94    tx_status: Cell<UARTStateTX>,
95
96    rx_buffer: TakeCell<'static, [u8]>,
97    rx_len: Cell<usize>,
98    rx_position: Cell<usize>,
99    rx_status: Cell<UARTStateRX>,
100
101    deferred_call: DeferredCall,
102}
103
104#[derive(Copy, Clone)]
105pub struct UartParams {
106    pub baud_rate: u32,
107}
108
109impl<'a> Uart<'a> {
110    pub fn new(base: StaticRef<UartRegisters>, clock_frequency: u32) -> Uart<'a> {
111        Uart {
112            registers: base,
113            clock_frequency,
114            stop_bits: Cell::new(hil::uart::StopBits::One),
115
116            tx_client: OptionalCell::empty(),
117            rx_client: OptionalCell::empty(),
118
119            tx_buffer: TakeCell::empty(),
120            tx_len: Cell::new(0),
121            tx_position: Cell::new(0),
122            tx_status: Cell::new(UARTStateTX::Idle),
123
124            rx_buffer: TakeCell::empty(),
125            rx_len: Cell::new(0),
126            rx_position: Cell::new(0),
127            rx_status: Cell::new(UARTStateRX::Idle),
128
129            deferred_call: DeferredCall::new(),
130        }
131    }
132
133    /// Configure GPIO pins for the UART.
134    pub fn initialize_gpio_pins(&self, tx: &gpio::GpioPin, rx: &gpio::GpioPin) {
135        tx.iof0();
136        rx.iof0();
137    }
138
139    fn set_baud_rate(&self, baud_rate: u32) {
140        let regs = self.registers;
141
142        //            f_clk
143        // f_baud = ---------
144        //           div + 1
145        let divisor = (self.clock_frequency / baud_rate) - 1;
146
147        regs.div.write(div::div.val(divisor));
148    }
149
150    fn get_stop_bits(&self) -> FieldValue<u32, txctrl::Register> {
151        match self.stop_bits.get() {
152            hil::uart::StopBits::One => txctrl::nstop::OneStopBit,
153            hil::uart::StopBits::Two => txctrl::nstop::TwoStopBits,
154        }
155    }
156
157    pub fn disable(&self) {
158        let regs = self.registers;
159        regs.txctrl.modify(txctrl::txen::CLEAR);
160        regs.rxctrl.modify(rxctrl::enable::CLEAR);
161
162        self.disable_rx_interrupt();
163        self.disable_tx_interrupt();
164    }
165
166    fn enable_tx_interrupt(&self) {
167        let regs = self.registers;
168        regs.ie.modify(interrupt::txwm::SET);
169    }
170
171    fn enable_rx_interrupt(&self) {
172        let regs = self.registers;
173        regs.ie.modify(interrupt::rxwm::SET);
174    }
175
176    fn disable_rx_interrupt(&self) {
177        let regs = self.registers;
178        regs.ie.modify(interrupt::rxwm::CLEAR);
179    }
180
181    fn disable_tx_interrupt(&self) {
182        let regs = self.registers;
183        regs.ie.modify(interrupt::txwm::CLEAR);
184    }
185
186    fn uart_is_writable(&self) -> bool {
187        !self.registers.txdata.is_set(txdata::full)
188    }
189
190    fn tx_progress(&self) {
191        while self.uart_is_writable() && self.tx_position.get() < self.tx_len.get() {
192            self.tx_buffer.map(|buf| {
193                self.registers
194                    .txdata
195                    .set(buf[self.tx_position.get()].into());
196                self.tx_position.replace(self.tx_position.get() + 1);
197            });
198        }
199    }
200
201    fn rx_progress(&self) {
202        while self.rx_position.get() < self.rx_len.get() {
203            let rxdata_copy = self.registers.rxdata.extract();
204
205            if rxdata_copy.read(rxdata::empty) == 1 {
206                break;
207            }
208
209            self.rx_buffer.map(|buf| {
210                buf[self.rx_position.get()] = rxdata_copy.read(rxdata::data) as u8;
211                self.rx_position.replace(self.rx_position.get() + 1);
212            });
213        }
214    }
215
216    pub fn handle_interrupt(&self) {
217        let regs = self.registers;
218
219        // Get a copy so we can check each interrupt flag in the register.
220        let pending_interrupts = regs.ip.extract();
221
222        // Determine why an interrupt occurred.
223        if self.tx_status.get() == UARTStateTX::Transmitting
224            && pending_interrupts.is_set(interrupt::txwm)
225        {
226            // Got a TX interrupt which means the number of bytes in the FIFO
227            // has fallen to zero. If there is more to send do that, otherwise
228            // send a callback to the client.
229
230            if self.tx_position.get() == self.tx_len.get() {
231                // We are done.
232                regs.txctrl.write(txctrl::txen::CLEAR);
233                self.disable_tx_interrupt();
234                self.tx_status.set(UARTStateTX::Idle);
235
236                // Signal client write is done
237                self.tx_client.map(|client| {
238                    self.tx_buffer.take().map(|buffer| {
239                        client.transmitted_buffer(buffer, self.tx_len.get(), Ok(()));
240                    });
241                });
242            } else {
243                self.tx_progress();
244            }
245        }
246
247        if self.rx_status.get() == UARTStateRX::Receiving
248            && pending_interrupts.is_set(interrupt::rxwm)
249        {
250            self.disable_rx_interrupt();
251            // Got a RX interrupt which means the number of bytes in the FIFO
252            // is greater than zero. Read them.
253            self.rx_progress();
254
255            if self.rx_position.get() == self.rx_len.get() {
256                // reception done
257                regs.rxctrl.write(rxctrl::enable::CLEAR);
258                self.rx_status.replace(UARTStateRX::Idle);
259
260                // Signal client read is done
261                self.rx_client.map(|client| {
262                    if let Some(buf) = self.rx_buffer.take() {
263                        client.received_buffer(
264                            buf,
265                            self.rx_len.get(),
266                            Ok(()),
267                            hil::uart::Error::None,
268                        );
269                    }
270                });
271            } else {
272                self.enable_rx_interrupt();
273            }
274        }
275    }
276
277    pub fn transmit_sync(&self, bytes: &[u8]) {
278        let regs = self.registers;
279
280        // Make sure the UART is enabled.
281        regs.txctrl
282            .write(txctrl::txen::SET + self.get_stop_bits() + txctrl::txcnt.val(1));
283
284        for b in bytes.iter() {
285            while regs.txdata.is_set(txdata::full) {}
286            regs.txdata.write(txdata::data.val(*b as u32));
287        }
288    }
289}
290
291impl DeferredCallClient for Uart<'_> {
292    fn register(&'static self) {
293        self.deferred_call.register(self)
294    }
295
296    fn handle_deferred_call(&self) {
297        if self.tx_status.get() == UARTStateTX::AbortRequested {
298            // alert client
299            self.tx_client.map(|client| {
300                self.tx_buffer.take().map(|buf| {
301                    client.transmitted_buffer(buf, self.tx_position.get(), Err(ErrorCode::CANCEL));
302                });
303            });
304            self.tx_status.set(UARTStateTX::Idle);
305        }
306
307        if self.rx_status.get() == UARTStateRX::AbortRequested {
308            // alert client
309            self.rx_client.map(|client| {
310                self.rx_buffer.take().map(|buf| {
311                    client.received_buffer(
312                        buf,
313                        self.rx_position.get(),
314                        Err(ErrorCode::CANCEL),
315                        hil::uart::Error::Aborted,
316                    );
317                });
318            });
319            self.rx_status.set(UARTStateRX::Idle);
320        }
321    }
322}
323
324impl hil::uart::Configure for Uart<'_> {
325    fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
326        // This chip does not support these features.
327        if params.parity != hil::uart::Parity::None {
328            return Err(ErrorCode::NOSUPPORT);
329        }
330        if params.hw_flow_control {
331            return Err(ErrorCode::NOSUPPORT);
332        }
333
334        // We can set the baud rate.
335        self.set_baud_rate(params.baud_rate);
336
337        // We need to save the stop bits because it is set in the TX register.
338        self.stop_bits.set(params.stop_bits);
339
340        Ok(())
341    }
342}
343
344impl<'a> hil::uart::Transmit<'a> for Uart<'a> {
345    fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
346        self.tx_client.set(client);
347    }
348
349    fn transmit_buffer(
350        &self,
351        tx_buffer: &'static mut [u8],
352        tx_len: usize,
353    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
354        if self.tx_status.get() != UARTStateTX::Idle {
355            Err((ErrorCode::BUSY, tx_buffer))
356        } else if tx_len == 0 || tx_len > tx_buffer.len() {
357            Err((ErrorCode::SIZE, tx_buffer))
358        } else {
359            self.tx_status.set(UARTStateTX::Transmitting);
360
361            // Save the buffer so we can keep sending it.
362            self.tx_buffer.replace(tx_buffer);
363            self.tx_len.set(tx_len);
364            self.tx_position.set(0);
365
366            // Enable transmissions and wait until the FIFO is empty before getting
367            // an interrupt.
368            self.registers
369                .txctrl
370                .write(txctrl::txen::SET + self.get_stop_bits() + txctrl::txcnt.val(1));
371
372            // Enable the interrupt so we know when we can keep writing.
373            self.enable_tx_interrupt();
374
375            Ok(())
376        }
377    }
378
379    fn transmit_abort(&self) -> Result<(), ErrorCode> {
380        if self.tx_status.get() != UARTStateTX::Idle {
381            self.registers.txctrl.write(txctrl::txen::CLEAR);
382            self.disable_tx_interrupt();
383            self.tx_status.set(UARTStateTX::AbortRequested);
384
385            self.deferred_call.set();
386
387            Err(ErrorCode::BUSY)
388        } else {
389            Ok(())
390        }
391    }
392
393    fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
394        Err(ErrorCode::FAIL)
395    }
396}
397
398impl<'a> hil::uart::Receive<'a> for Uart<'a> {
399    fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
400        self.rx_client.set(client);
401    }
402
403    fn receive_buffer(
404        &self,
405        rx_buffer: &'static mut [u8],
406        rx_len: usize,
407    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
408        if self.rx_status.get() != UARTStateRX::Idle {
409            Err((ErrorCode::BUSY, rx_buffer))
410        } else if rx_len > rx_buffer.len() {
411            Err((ErrorCode::SIZE, rx_buffer))
412        } else {
413            self.rx_status.set(UARTStateRX::Receiving);
414
415            self.rx_buffer.put(Some(rx_buffer));
416            self.rx_position.set(0);
417            self.rx_len.set(rx_len);
418
419            // Enable receptions and wait until the FIFO has at least one byte
420            // before getting an interrupt.
421            self.registers
422                .rxctrl
423                .write(rxctrl::enable::SET + rxctrl::counter.val(0));
424
425            self.enable_rx_interrupt();
426
427            Ok(())
428        }
429    }
430
431    fn receive_abort(&self) -> Result<(), ErrorCode> {
432        if self.rx_status.get() != UARTStateRX::Idle {
433            self.registers.rxctrl.write(rxctrl::enable::CLEAR);
434            self.disable_rx_interrupt();
435            self.rx_status.set(UARTStateRX::AbortRequested);
436
437            self.deferred_call.set();
438
439            Err(ErrorCode::BUSY)
440        } else {
441            Ok(())
442        }
443    }
444
445    fn receive_word(&self) -> Result<(), ErrorCode> {
446        Err(ErrorCode::FAIL)
447    }
448}