rdif-serial 0.5.1

Driver Interface base definition.
Documentation
use core::cell::UnsafeCell;

use alloc::{
    boxed::Box,
    sync::{Arc, Weak},
};
use rdif_base::{DriverGeneric, KError};

use crate::{
    Config, ConfigError, DataBits, InterruptMask, NotMatchError, Parity, Register, StopBits,
    TransferError,
};

pub struct SerialRaw<T: Register> {
    inner: T,
    tx: Option<SenderRaw<T>>,
    rx: Option<RecieverRaw<T>>,
    handler: Option<IrqHandlerRaw<T>>,
}

impl<T: Register> SerialRaw<T> {
    pub fn new(inner: T) -> Self {
        Self {
            tx: Some(SenderRaw::new(inner.clone())),
            rx: Some(RecieverRaw::new(inner.clone())),
            handler: Some(IrqHandlerRaw::new(inner.clone())),
            inner,
        }
    }

    pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
        self.inner.set_config(config)
    }

    pub fn baudrate(&self) -> u32 {
        self.inner.baudrate()
    }
    pub fn data_bits(&self) -> DataBits {
        self.inner.data_bits()
    }
    pub fn stop_bits(&self) -> StopBits {
        self.inner.stop_bits()
    }
    pub fn parity(&self) -> Parity {
        self.inner.parity()
    }
    pub fn clock_freq(&self) -> u32 {
        self.inner.clock_freq()
    }

    pub fn enable_loopback(&mut self) {
        self.inner.enable_loopback()
    }
    pub fn disable_loopback(&mut self) {
        self.inner.disable_loopback()
    }
    pub fn is_loopback_enabled(&self) -> bool {
        self.inner.is_loopback_enabled()
    }

    pub fn enable_interrupts(&mut self, mask: InterruptMask) {
        self.inner.set_irq_mask(mask | self.inner.get_irq_mask())
    }
    pub fn disable_interrupts(&mut self, mask: InterruptMask) {
        self.inner.set_irq_mask(self.inner.get_irq_mask() & !mask)
    }

    pub fn get_enabled_interrupts(&self) -> InterruptMask {
        self.inner.get_irq_mask()
    }

    pub fn take_tx(&mut self) -> Option<SenderRaw<T>> {
        self.tx.take()
    }

    pub fn take_rx(&mut self) -> Option<RecieverRaw<T>> {
        self.rx.take()
    }

    pub fn irq_handler(&mut self) -> Option<IrqHandlerRaw<T>> {
        self.handler.take()
    }

    pub fn set_tx(&mut self, tx: SenderRaw<T>) -> Result<(), NotMatchError> {
        if self.inner.get_base() != tx.inner.get_base() {
            return Err(NotMatchError);
        }
        self.tx.replace(tx);
        Ok(())
    }

    pub fn set_rx(&mut self, rx: RecieverRaw<T>) -> Result<(), NotMatchError> {
        if self.inner.get_base() != rx.inner.get_base() {
            return Err(NotMatchError);
        }
        self.rx.replace(rx);
        Ok(())
    }

    pub fn set_irq_handler(&mut self, handler: IrqHandlerRaw<T>) -> Result<(), NotMatchError> {
        if self.inner.get_base() != handler.get_base() {
            return Err(NotMatchError);
        }
        self.handler.replace(handler);
        Ok(())
    }
}

pub struct Serial<T: Register> {
    inner: Arc<UnsafeCell<SerialRaw<T>>>,
}

unsafe impl<T: Register> Send for Serial<T> {}
unsafe impl<T: Register> Sync for Serial<T> {}

impl<T: Register> Serial<T> {
    pub fn new(inner: T) -> Self {
        Self {
            inner: Arc::new(UnsafeCell::new(SerialRaw::new(inner))),
        }
    }

    fn inner_mut(&mut self) -> &mut SerialRaw<T> {
        unsafe { &mut *self.inner.get() }
    }

    fn inner(&self) -> &SerialRaw<T> {
        unsafe { &*self.inner.get() }
    }

    pub fn open(&mut self) -> Result<(), KError> {
        self.inner_mut().inner.open();
        Ok(())
    }

    pub fn close(&mut self) -> Result<(), KError> {
        self.inner_mut().inner.close();
        Ok(())
    }
}

impl<T: Register> crate::Interface for Serial<T> {
    fn base(&self) -> usize {
        self.inner().inner.get_base()
    }

    fn take_tx(&mut self) -> Option<Box<dyn crate::TSender>> {
        self.inner_mut().take_tx().map(|s| {
            Box::new(Sender {
                inner: Some(s),
                s: Arc::downgrade(&self.inner),
            }) as _
        })
    }

    fn take_rx(&mut self) -> Option<Box<dyn crate::TReciever>> {
        self.inner_mut().take_rx().map(|r| {
            Box::new(Reciever {
                inner: Some(r),
                s: Arc::downgrade(&self.inner),
            }) as _
        })
    }

    fn irq_handler(&mut self) -> Option<Box<dyn crate::TIrqHandler>> {
        self.inner_mut().irq_handler().map(|h| {
            Box::new(IrqHandler {
                inner: Some(h),
                s: Arc::downgrade(&self.inner),
            }) as _
        })
    }

    fn set_config(&mut self, config: &crate::Config) -> Result<(), crate::ConfigError> {
        self.inner_mut().set_config(config)
    }

    fn baudrate(&self) -> u32 {
        self.inner().baudrate()
    }

    fn data_bits(&self) -> crate::DataBits {
        self.inner().data_bits()
    }

    fn stop_bits(&self) -> crate::StopBits {
        self.inner().stop_bits()
    }

    fn parity(&self) -> crate::Parity {
        self.inner().parity()
    }

    fn clock_freq(&self) -> u32 {
        self.inner().clock_freq()
    }

    fn enable_loopback(&mut self) {
        self.inner_mut().enable_loopback()
    }

    fn disable_loopback(&mut self) {
        self.inner_mut().disable_loopback()
    }

    fn is_loopback_enabled(&self) -> bool {
        self.inner().is_loopback_enabled()
    }

    fn enable_interrupts(&mut self, mask: InterruptMask) {
        self.inner_mut().enable_interrupts(mask)
    }

    fn disable_interrupts(&mut self, mask: InterruptMask) {
        self.inner_mut().disable_interrupts(mask)
    }

    fn get_enabled_interrupts(&self) -> InterruptMask {
        self.inner().get_enabled_interrupts()
    }
}

impl<T: Register> DriverGeneric for Serial<T> {
    fn open(&mut self) -> Result<(), KError> {
        self.inner_mut().inner.open();
        Ok(())
    }

    fn close(&mut self) -> Result<(), KError> {
        self.inner_mut().inner.close();
        Ok(())
    }
}

pub struct SenderRaw<T: Register> {
    inner: T,
}

impl<T: Register> SenderRaw<T> {
    fn new(inner: T) -> Self {
        Self { inner }
    }
    pub fn send(&mut self, buf: &[u8]) -> usize {
        self.inner.write_buf(buf)
    }
}

pub struct Sender<T: Register> {
    inner: Option<SenderRaw<T>>,
    s: Weak<UnsafeCell<SerialRaw<T>>>,
}

unsafe impl<T: Register> Send for Sender<T> {}

impl<T: Register> Drop for Sender<T> {
    fn drop(&mut self) {
        if let Some(s) = self.s.upgrade() {
            unsafe {
                let s = &mut *s.get();
                let _ = s.set_tx(self.inner.take().unwrap());
            }
        }
    }
}

impl<T: Register> crate::TSender for Sender<T> {
    fn send(&mut self, buf: &[u8]) -> usize {
        self.inner.as_mut().unwrap().send(buf)
    }
}

pub struct RecieverRaw<T: Register> {
    inner: T,
}

impl<T: Register> RecieverRaw<T> {
    fn new(inner: T) -> Self {
        Self { inner }
    }

    pub fn recive(&mut self, buf: &mut [u8]) -> Result<usize, TransferError> {
        let n = self.inner.read_buf(buf)?;
        Ok(n)
    }

    pub fn clean_fifo(&mut self) {
        let mut buff = [0u8; 16];
        while let Ok(n) = self.recive(&mut buff) {
            if n < 16 {
                break;
            }
        }
    }
}

pub struct Reciever<T: Register> {
    inner: Option<RecieverRaw<T>>,
    s: Weak<UnsafeCell<SerialRaw<T>>>,
}

unsafe impl<T: Register> Send for Reciever<T> {}

impl<T: Register> crate::TReciever for Reciever<T> {
    fn recive(&mut self, buf: &mut [u8]) -> Result<usize, TransferError> {
        self.inner.as_mut().unwrap().recive(buf)
    }
    fn clean_fifo(&mut self) {
        self.inner.as_mut().unwrap().clean_fifo();
    }
}

impl<T: Register> Drop for Reciever<T> {
    fn drop(&mut self) {
        if let Some(s) = self.s.upgrade() {
            unsafe {
                let s = &mut *s.get();
                let _ = s.set_rx(self.inner.take().unwrap());
            }
        }
    }
}

pub struct IrqHandlerRaw<T: Register> {
    inner: UnsafeCell<T>,
}

unsafe impl<T: Register> Send for IrqHandlerRaw<T> {}
unsafe impl<T: Register> Sync for IrqHandlerRaw<T> {}

impl<T: Register> IrqHandlerRaw<T> {
    fn new(inner: T) -> Self {
        Self {
            inner: UnsafeCell::new(inner),
        }
    }
    pub fn clean_interrupt_status(&self) -> InterruptMask {
        unsafe { (*self.inner.get()).clean_interrupt_status() }
    }

    fn get_base(&self) -> usize {
        unsafe { (*self.inner.get()).get_base() }
    }
}

pub struct IrqHandler<T: Register> {
    inner: Option<IrqHandlerRaw<T>>,
    s: Weak<UnsafeCell<SerialRaw<T>>>,
}
unsafe impl<T: Register> Send for IrqHandler<T> {}
unsafe impl<T: Register> Sync for IrqHandler<T> {}

impl<T: Register> crate::TIrqHandler for IrqHandler<T> {
    fn clean_interrupt_status(&self) -> InterruptMask {
        self.inner.as_ref().unwrap().clean_interrupt_status()
    }
}

impl<T: Register> Drop for IrqHandler<T> {
    fn drop(&mut self) {
        if let Some(s) = self.s.upgrade() {
            unsafe {
                let s = &mut *s.get();
                let _ = s.set_irq_handler(self.inner.take().unwrap());
            }
        }
    }
}