107 lines
No EOL
2.3 KiB
Rust
107 lines
No EOL
2.3 KiB
Rust
use core::fmt::Write;
|
|
|
|
// todo: this should probably be in the dev module
|
|
|
|
pub trait Serial {
|
|
fn put(&self, c: u8);
|
|
fn putstr(&self, s: &str);
|
|
fn put_bytes(&self, s: &[u8]);
|
|
fn get(&self) -> Option<u8>;
|
|
}
|
|
|
|
pub struct UART {
|
|
offset: usize,
|
|
}
|
|
|
|
impl UART {
|
|
pub fn init(&self) {
|
|
let offset = self.offset as *mut u8;
|
|
unsafe {
|
|
// word length
|
|
let lcr = (1 << 0) | (1 << 1);
|
|
offset.add(3).write_volatile(lcr);
|
|
|
|
// enable fifo
|
|
offset.add(2).write_volatile(1 << 0);
|
|
// receiver buffer interrupts
|
|
offset.add(1).write_volatile(1 << 0);
|
|
|
|
// divisor boilerplate code, maybe check this later if we want custom baud rate
|
|
let divisor: u16 = 592;
|
|
let dlo: u8 = (divisor & 0xff) as u8;
|
|
let dhi: u8 = (divisor >> 8) as u8;
|
|
|
|
offset.add(3).write_volatile(lcr | 1 << 7);
|
|
offset.add(0).write_volatile(dlo);
|
|
offset.add(1).write_volatile(dhi);
|
|
offset.add(3).write_volatile(lcr);
|
|
}
|
|
}
|
|
|
|
pub fn new_and_init(offset: usize) -> UART {
|
|
let uart = UART { offset: offset };
|
|
uart.init();
|
|
uart
|
|
}
|
|
|
|
pub const fn new(offset: usize) -> UART {
|
|
let uart = UART { offset: offset };
|
|
uart
|
|
}
|
|
|
|
pub fn get(&self) -> Option<u8> {
|
|
unsafe {
|
|
if (self.offset as *mut u8).add(5).read_volatile() & 1 == 0 {
|
|
None
|
|
} else {
|
|
Some((self.offset as *mut u8).add(0).read_volatile())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn put(&self, c: u8) {
|
|
unsafe {
|
|
(self.offset as *mut u8).add(0).write_volatile(c);
|
|
}
|
|
}
|
|
|
|
pub fn putstr(&self, s: &str) {
|
|
for c in s.bytes() {
|
|
self.put(c);
|
|
}
|
|
}
|
|
|
|
pub fn put_bytes(&self, s: &[u8]) {
|
|
for c in s {
|
|
self.put(*c);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Write for UART {
|
|
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
|
for c in s.bytes() {
|
|
self.put(c);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Serial for UART {
|
|
fn put(&self, c: u8) {
|
|
self.put(c);
|
|
}
|
|
|
|
fn putstr(&self, s: &str) {
|
|
self.putstr(s);
|
|
}
|
|
|
|
fn put_bytes(&self, s: &[u8]) {
|
|
self.put_bytes(s);
|
|
}
|
|
|
|
fn get(&self) -> Option<u8> {
|
|
self.get()
|
|
}
|
|
} |