derive_mmio_example/
lib.rs

1//! # derive-mmio-example
2//!
3//! A very basic peripheral example using derive-mmio and bitbybit
4
5#![no_std]
6#![deny(missing_docs)]
7
8use arbitrary_int::u23;
9use bitbybit::{bitenum, bitfield};
10
11/// Represents a UART
12pub struct Uart<'a> {
13    regs: MmioUartRegisters<'a>,
14}
15
16impl<'a> Uart<'a> {
17    /// Create a UART driver, with the UART at the given address
18    pub const fn new(regs: MmioUartRegisters<'a>) -> Uart<'a> {
19        Uart { regs }
20    }
21
22    /// Configure the UART
23    pub fn configure(&mut self, enabled: bool, baud: u32, parity: Parity) {
24        self.regs.modify_control(|w| {
25            w.with_baud_rate(u23::from_u32(baud));
26            w.with_enable(enabled);
27            w.with_parity(parity);
28            w
29        });
30    }
31
32    /// Transmit a byte
33    ///
34    /// Blocks until space available
35    pub fn transmit(&mut self, byte: u8) {
36        while !self.regs.read_status().tx_ready() {
37            core::hint::spin_loop();
38        }
39        self.regs.write_fifo(byte as u32);
40    }
41}
42
43/// Describes the UART's registers
44///
45/// Use the [`MmioUartRegisters`] type to access a particular UART at a particular address.
46#[derive(derive_mmio::Mmio)]
47#[repr(C)]
48pub struct UartRegisters {
49    /// Data FIFO
50    ///
51    /// * Read here to get a byte from the FIFO
52    /// * Write here to put a byte into the FIFO
53    #[mmio(Read, Write)]
54    pub fifo: u32,
55    /// Control Register
56    ///
57    /// Adjust various UART settings
58    #[mmio(Read, Write, Modify)]
59    pub control: Control,
60    /// Status Register
61    ///
62    /// Read-only UART status
63    #[mmio(PureRead)]
64    pub status: Status,
65}
66
67/// Control Register
68#[bitfield(u32, debug, exclusive)]
69pub struct Control {
70    /// Parity bits for a byte
71    #[bits(24..=25, rw)]
72    parity: Option<Parity>,
73    /// Baud Rate
74    #[bits(1..=23, rw)]
75    baud_rate: u23,
76    /// Is this peripheral enabled
77    #[bit(0, rw)]
78    enable: bool,
79}
80
81/// Parity bits for a byte
82#[derive(Debug)]
83#[bitenum(u2, exhaustive = false)]
84pub enum Parity {
85    /// No parity
86    None = 0,
87    /// Odd parity
88    Odd = 1,
89    /// Even parity
90    Even = 2,
91}
92
93/// Status Register
94#[bitfield(u32, debug, exclusive)]
95pub struct Status {
96    /// Does the RX FIFO have data?
97    #[bit(1, rw)]
98    rx_ready: bool,
99    /// Does the TX FIFO have data?
100    #[bit(0, rw)]
101    tx_ready: bool,
102}