Skip to content

Commit a90709f

Browse files
committed
Remove some methods from public interface.
Clients should not need to access registers directly; if they need functionality which is not currently exposed then it should be added to this crate. Also removed register access methods, as they didn't really add anything.
1 parent 331a851 commit a90709f

File tree

3 files changed

+41
-153
lines changed

3 files changed

+41
-153
lines changed

uart8250/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ This crate provides a struct with many methods to operate an 8250 UART.
88

99
#![no_std]
1010

11-
pub mod registers;
11+
mod registers;
1212
mod uart;
1313

14-
pub use registers::{FCR, IER, IIR, LCR, LSR, MCR, MSR};
1514
pub use uart::{ChipFifoInfo, InterruptType, MmioUart8250, Parity};

uart8250/src/registers.rs

Lines changed: 2 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use core::u8;
22
use tock_registers::{
3-
interfaces::{Readable, Writeable},
43
register_bitfields, register_structs,
54
registers::{Aliased, ReadOnly, ReadWrite},
65
};
@@ -27,14 +26,14 @@ register_structs! {
2726
/// | +6 | x | Read | MSR | Modem Status Register |
2827
/// | +7 | x | Read/Write | SR | Scratch Register |
2928
pub Registers {
30-
(0x00 => thr_rbr_dll: ReadWrite<u8>),
29+
(0x00 => pub thr_rbr_dll: ReadWrite<u8>),
3130
(0x01 => pub ier_dlh: ReadWrite<u8, IER::Register>),
3231
(0x02 => pub iir_fcr: Aliased<u8, IIR::Register, FCR::Register>),
3332
(0x03 => pub lcr: ReadWrite<u8, LCR::Register>),
3433
(0x04 => pub mcr: ReadWrite<u8, MCR::Register>),
3534
(0x05 => pub lsr: ReadOnly<u8, LSR::Register>),
3635
(0x06 => pub msr: ReadOnly<u8, MSR::Register>),
37-
(0x07 => scratch: ReadWrite<u8>),
36+
(0x07 => pub scratch: ReadWrite<u8>),
3837
(0x08 => @END),
3938
}
4039
}
@@ -210,96 +209,4 @@ impl Registers {
210209
pub fn from_base_address(base_address: usize) -> &'static mut Self {
211210
unsafe { &mut *(base_address as *mut crate::registers::Registers) }
212211
}
213-
214-
/// write THR (offset + 0)
215-
///
216-
/// Write Transmitter Holding Buffer to send data
217-
///
218-
/// > ## Transmitter Holding Buffer/Receiver Buffer
219-
/// >
220-
/// > Offset: +0 . The Transmit and Receive buffers are related, and often even use the very same memory. This is also one of the areas where later versions of the 8250 chip have a significant impact, as the later models incorporate some internal buffering of the data within the chip before it gets transmitted as serial data. The base 8250 chip can only receive one byte at a time, while later chips like the 16550 chip will hold up to 16 bytes either to transmit or to receive (sometimes both... depending on the manufacturer) before you have to wait for the character to be sent. This can be useful in multi-tasking environments where you have a computer doing many things, and it may be a couple of milliseconds before you get back to dealing with serial data flow.
221-
/// >
222-
/// > These registers really are the "heart" of serial data communication, and how data is transferred from your software to another computer and how it gets data from other devices. Reading and Writing to these registers is simply a matter of accessing the Port I/O address for the respective UART.
223-
/// >
224-
/// > If the receive buffer is occupied or the FIFO is full, the incoming data is discarded and the Receiver Line Status interrupt is written to the IIR register. The Overrun Error bit is also set in the Line Status Register.
225-
#[inline]
226-
pub fn write_thr(&self, value: u8) {
227-
self.thr_rbr_dll.set(value)
228-
}
229-
230-
/// read RBR (offset + 0)
231-
///
232-
/// Read Receiver Buffer to get data
233-
#[inline]
234-
pub fn read_rbr(&self) -> u8 {
235-
self.thr_rbr_dll.get()
236-
}
237-
238-
/// read DLL (offset + 0)
239-
///
240-
/// get divisor latch low byte in the register
241-
///
242-
/// > ## Divisor Latch Bytes
243-
/// >
244-
/// > Offset: +0 and +1 . The Divisor Latch Bytes are what control the baud rate of the modem. As you might guess from the name of this register, it is used as a divisor to determine what baud rate that the chip is going to be transmitting at.
245-
///
246-
/// Used clock 1.8432 MHz as example, first divide 16 and get 115200. Then use the formula to get divisor latch value:
247-
///
248-
/// *DivisorLatchValue = 115200 / BaudRate*
249-
///
250-
/// This gives the following table:
251-
///
252-
/// | Baud Rate | Divisor (in decimal) | Divisor Latch High Byte | Divisor Latch Low Byte |
253-
/// | --------- | -------------------- | ----------------------- | ---------------------- |
254-
/// | 50 | 2304 | $09 | $00 |
255-
/// | 110 | 1047 | $04 | $17 |
256-
/// | 220 | 524 | $02 | $0C |
257-
/// | 300 | 384 | $01 | $80 |
258-
/// | 600 | 192 | $00 | $C0 |
259-
/// | 1200 | 96 | $00 | $60 |
260-
/// | 2400 | 48 | $00 | $30 |
261-
/// | 4800 | 24 | $00 | $18 |
262-
/// | 9600 | 12 | $00 | $0C |
263-
/// | 19200 | 6 | $00 | $06 |
264-
/// | 38400 | 3 | $00 | $03 |
265-
/// | 57600 | 2 | $00 | $02 |
266-
/// | 115200 | 1 | $00 | $01 |
267-
#[inline]
268-
pub fn read_dll(&self) -> u8 {
269-
self.thr_rbr_dll.get()
270-
}
271-
272-
/// write DLL (offset + 0)
273-
///
274-
/// set divisor latch low byte in the register
275-
#[inline]
276-
pub fn write_dll(&self, value: u8) {
277-
self.thr_rbr_dll.set(value)
278-
}
279-
280-
/// read DLH (offset + 1)
281-
///
282-
/// get divisor latch high byte in the register
283-
#[inline]
284-
pub fn read_dlh(&self) -> u8 {
285-
self.ier_dlh.get()
286-
}
287-
288-
/// write DLH (offset + 1)
289-
///
290-
/// set divisor latch high byte in the register
291-
#[inline]
292-
pub fn write_dlh(&self, value: u8) {
293-
self.ier_dlh.set(value)
294-
}
295-
296-
#[inline]
297-
pub fn read_sr(&self) -> u8 {
298-
self.scratch.get()
299-
}
300-
301-
#[inline]
302-
pub fn write_sr(&self, value: u8) {
303-
self.scratch.set(value)
304-
}
305212
}

uart8250/src/uart.rs

Lines changed: 38 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use tock_registers::{
66
LocalRegisterCopy, RegisterLongName,
77
};
88

9-
use crate::registers::{Registers, FCR, IER, IIR, LCR, LSR, MCR, MSR};
9+
use crate::registers::{Registers, FCR, IER, IIR, LCR, LSR, MSR};
1010

1111
pub type ChipFifoInfo = IIR::FifoInfo::Value;
1212
pub type InterruptType = IIR::InterruptType::Value;
@@ -35,11 +35,13 @@ impl<'a> MmioUart8250<'a> {
3535
self.set_divisor(clock, baud_rate);
3636

3737
// Disable DLAB and set word length 8 bits, no parity, 1 stop bit
38-
self.set_lcr(LCR::Parity::No + LCR::STOP_BITS::One + LCR::WORD_LENGTH::Bits8);
38+
self.reg
39+
.lcr
40+
.write(LCR::Parity::No + LCR::STOP_BITS::One + LCR::WORD_LENGTH::Bits8);
3941
// Enable FIFO
40-
self.set_fcr(FCR::Enable::SET);
42+
self.reg.iir_fcr.write(FCR::Enable::SET);
4143
// No modem control
42-
self.set_mcr(FieldValue::<u8, _>::new(0, 0, 0));
44+
self.reg.mcr.write(FieldValue::<u8, _>::new(0, 0, 0));
4345
// Enable received_data_available_interrupt
4446
self.enable_received_data_available_interrupt();
4547
// Enable transmitter_holding_register_empty_interrupt
@@ -56,7 +58,7 @@ impl<'a> MmioUart8250<'a> {
5658
/// Returns `None` when data is not ready (RBR\[0\] != 1)
5759
pub fn read_byte(&self) -> Option<u8> {
5860
if self.is_data_ready() {
59-
Some(self.reg.read_rbr())
61+
Some(self.reg.thr_rbr_dll.get())
6062
} else {
6163
None
6264
}
@@ -66,16 +68,43 @@ impl<'a> MmioUart8250<'a> {
6668
///
6769
/// TODO: This currently ignores errors.
6870
pub fn write_byte(&self, byte: u8) {
69-
self.reg.write_thr(byte);
71+
self.reg.thr_rbr_dll.set(byte);
7072
}
7173

72-
/// Set divisor latch according to clock and baud_rate, then set DLAB to false
74+
/// Sets DLAB to true, sets divisor latch according to clock and baud_rate, then sets DLAB to
75+
/// false.
76+
///
77+
/// > ## Divisor Latch Bytes
78+
/// >
79+
/// > Offset: +0 and +1 . The Divisor Latch Bytes are what control the baud rate of the modem. As you might guess from the name of this register, it is used as a divisor to determine what baud rate that the chip is going to be transmitting at.
80+
///
81+
/// Used clock 1.8432 MHz as example, first divide 16 and get 115200. Then use the formula to get divisor latch value:
82+
///
83+
/// *DivisorLatchValue = 115200 / BaudRate*
84+
///
85+
/// This gives the following table:
86+
///
87+
/// | Baud Rate | Divisor (in decimal) | Divisor Latch High Byte | Divisor Latch Low Byte |
88+
/// | --------- | -------------------- | ----------------------- | ---------------------- |
89+
/// | 50 | 2304 | $09 | $00 |
90+
/// | 110 | 1047 | $04 | $17 |
91+
/// | 220 | 524 | $02 | $0C |
92+
/// | 300 | 384 | $01 | $80 |
93+
/// | 600 | 192 | $00 | $C0 |
94+
/// | 1200 | 96 | $00 | $60 |
95+
/// | 2400 | 48 | $00 | $30 |
96+
/// | 4800 | 24 | $00 | $18 |
97+
/// | 9600 | 12 | $00 | $0C |
98+
/// | 19200 | 6 | $00 | $06 |
99+
/// | 38400 | 3 | $00 | $03 |
100+
/// | 57600 | 2 | $00 | $02 |
101+
/// | 115200 | 1 | $00 | $01 |
73102
#[inline]
74103
pub fn set_divisor(&self, clock: usize, baud_rate: usize) {
75104
self.enable_divisor_latch_accessible();
76105
let divisor = clock / (16 * baud_rate);
77-
self.reg.write_dll(divisor as u8);
78-
self.reg.write_dlh((divisor >> 8) as u8);
106+
self.reg.thr_rbr_dll.set(divisor as u8);
107+
self.reg.ier_dlh.set((divisor >> 8) as u8);
79108
self.disable_divisor_latch_accessible();
80109
}
81110

@@ -248,11 +277,6 @@ impl<'a> MmioUart8250<'a> {
248277
self.reg.lcr.read(LCR::DLAB) != 0
249278
}
250279

251-
/// toggle DLAB
252-
pub fn toggle_divisor_latch_accessible(&self) {
253-
toggle_field(&self.reg.lcr, LCR::DLAB);
254-
}
255-
256280
/// enable DLAB
257281
pub fn enable_divisor_latch_accessible(&self) {
258282
self.reg.lcr.modify(LCR::DLAB::SET)
@@ -306,42 +330,6 @@ impl<'a> MmioUart8250<'a> {
306330
}
307331
}
308332

309-
/// Sets FCR bitflags
310-
#[inline]
311-
pub fn set_fcr(&self, fcr: FieldValue<u8, FCR::Register>) {
312-
self.reg.iir_fcr.write(fcr)
313-
}
314-
315-
/// Gets LCR bitflags
316-
#[inline]
317-
pub fn lcr(&self) -> LocalRegisterCopy<u8, LCR::Register> {
318-
self.reg.lcr.extract()
319-
}
320-
321-
/// Sets LCR bitflags
322-
#[inline]
323-
pub fn set_lcr(&self, lcr: FieldValue<u8, LCR::Register>) {
324-
self.reg.lcr.write(lcr)
325-
}
326-
327-
/// Gets MCR bitflags
328-
#[inline]
329-
pub fn mcr(&self) -> LocalRegisterCopy<u8, MCR::Register> {
330-
self.reg.mcr.extract()
331-
}
332-
333-
/// Sets MCR bitflags
334-
#[inline]
335-
pub fn set_mcr(&self, mcr: FieldValue<u8, MCR::Register>) {
336-
self.reg.mcr.write(mcr)
337-
}
338-
339-
/// Get LSR bitflags
340-
#[inline]
341-
pub fn lsr(&self) -> LocalRegisterCopy<u8, LSR::Register> {
342-
self.reg.lsr.extract()
343-
}
344-
345333
/// get whether there is an error in received FIFO
346334
pub fn is_received_fifo_error(&self) -> bool {
347335
self.reg.lsr.is_set(LSR::RFE)
@@ -377,12 +365,6 @@ impl<'a> MmioUart8250<'a> {
377365
self.reg.lsr.is_set(LSR::DR)
378366
}
379367

380-
/// Get MSR bitflags
381-
#[inline]
382-
pub fn msr(&self) -> LocalRegisterCopy<u8, MSR::Register> {
383-
self.reg.msr.extract()
384-
}
385-
386368
pub fn is_carrier_detect(&self) -> bool {
387369
self.reg.msr.is_set(MSR::CD)
388370
}

0 commit comments

Comments
 (0)