tock_registers_example/
lib.rs

1//! # tock-registers-example
2//!
3//! A very basic peripheral example using tock-registers
4
5#![no_std]
6
7// I can't seem add enough documentation to the bitflags! code to satisfy this
8// #![deny(missing_docs)]
9
10use tock_registers::registers::{ReadOnly, ReadWrite};
11use tock_registers::{register_bitfields, register_structs};
12
13/// Represents a UART
14pub struct Uart {
15    regs: &'static mut UartRegisters,
16}
17
18impl Uart {
19    /// Create a UART driver, with the UART at the given address
20    ///
21    /// # Safety
22    ///
23    /// The pointer `addr` must point to a valid UART structure, with
24    /// appropriate alignment.
25    pub const unsafe fn new(addr: *mut UartRegisters) -> Uart {
26        Uart {
27            regs: unsafe { &mut *addr },
28        }
29    }
30
31    /// Configure the UART
32    pub fn configure(&mut self, enabled: bool, baud: u32, parity: Control::parity::Value) {
33        use tock_registers::interfaces::ReadWriteable;
34
35        self.regs.control.modify(
36            Control::parity.val(parity as u32)
37                + Control::enable.val(enabled as u32)
38                + Control::baud_rate.val(baud),
39        );
40    }
41
42    /// Transmit a byte
43    ///
44    /// Blocks until space available
45    pub fn transmit(&mut self, byte: u8) {
46        use tock_registers::interfaces::{Readable, Writeable};
47
48        while self.regs.status.read(Status::tx_ready) == 0 {
49            core::hint::spin_loop();
50        }
51        self.regs.fifo.set(byte as u32);
52    }
53}
54
55register_structs! {
56    /// Describes the UART's registers
57    pub UartRegisters {
58        /// Data FIFO
59        ///
60        /// * Read here to get a byte from the FIFO
61        /// * Write here to put a byte into the FIFO
62        (0x000 => pub fifo: ReadWrite<u32>),
63        /// Control Register
64        ///
65        /// Adjust various UART settings
66        (0x004 => pub control: ReadWrite<u32, Control::Register>),
67        /// Status Register
68        ///
69        /// Read-only UART status
70        (0x008 => pub status: ReadOnly<u32, Status::Register>),
71        // End of peripheral
72        (0x00C => @END),
73    }
74}
75
76register_bitfields![u32,
77     /// Control Register
78    pub Control [
79        /// Parity bits for a byte
80        parity OFFSET(24) NUMBITS(2) [
81            /// No Parity
82            None = 0,
83            /// Odd Parity
84            Odd = 1,
85            /// Even Parity
86            Even = 3
87        ],
88        /// Baud Rate
89        baud_rate OFFSET(1) NUMBITS(23) [],
90        /// Is this peripheral enabled
91        enable OFFSET(0) NUMBITS(1) [],
92    ],
93    /// Status Register
94    pub Status [
95        rx_ready OFFSET(1) NUMBITS(1) [
96            Yes = 1,
97            No = 0
98        ],
99        tx_ready OFFSET(0) NUMBITS(1) [
100            Yes = 1,
101            No = 0
102        ]
103    ]
104];