#![no_std]
pub trait SerialInstance<S> {
fn init(&self, serial: &Serial<S>);
fn write(&self, s: &str);
}
pub struct SerialConfig<S> {
name: &'static str,
physbase: usize,
baud: u32,
clk: u32,
driver: S,
}
impl<S: SerialInstance<S> + Copy> SerialConfig<S> {
pub fn new(driver: S) -> Self {
Self {
name: "",
physbase: 0,
baud: 0,
clk: 0,
driver,
}
}
#[inline]
pub fn name(&mut self, name: &'static str) {
self.name = name;
}
#[inline]
pub fn physbase(&mut self, physbase: usize) {
self.physbase = physbase;
}
#[inline]
pub fn baud(&mut self, baud: u32) {
self.baud = baud;
}
#[inline]
pub fn clk(&mut self, clk: u32) {
self.clk = clk;
}
#[inline]
pub fn init(&self) -> Serial<S> {
Serial::init(self)
}
}
pub struct Serial<S> {
name: &'static str,
physbase: usize,
pub virtbase: usize,
pub baud: u32,
pub clk: u32,
available: bool,
driver: S,
}
impl<S: SerialInstance<S> + Copy> Serial<S> {
fn init(c: &SerialConfig<S>) -> Self {
let mut serial = Self {
name: c.name,
physbase: c.physbase,
virtbase: 0,
baud: c.baud,
clk: c.clk,
available: false,
driver: c.driver,
};
serial.virtbase = serial.physbase;
serial.driver.init(&serial);
serial.available = true;
serial
}
pub fn name(&self) -> &'static str {
self.name
}
pub fn available(&self) -> bool {
self.available
}
}