rdif-pinctrl 0.1.2

Driver Interface pin control definition.
Documentation
use crate::{GpioBankId, GpioIrqSourceId, GpioLineId};

pub const MAX_GPIO_IRQ_EVENTS: usize = 16;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GpioIrqTrigger {
    EdgeRising,
    EdgeFalling,
    EdgeBoth,
    LevelHigh,
    LevelLow,
    Unknown,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GpioIrqError {
    Overflow,
    Spurious,
    Controller,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GpioLineEvent {
    pub line: GpioLineId,
    pub trigger: GpioIrqTrigger,
}

impl GpioLineEvent {
    pub const fn new(line: GpioLineId, trigger: GpioIrqTrigger) -> Self {
        Self { line, trigger }
    }

    const fn empty() -> Self {
        Self {
            line: GpioLineId::new(GpioBankId::new(0), 0),
            trigger: GpioIrqTrigger::Unknown,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GpioIrqEvent {
    source: Option<GpioIrqSourceId>,
    lines: [GpioLineEvent; MAX_GPIO_IRQ_EVENTS],
    len: usize,
    error: Option<GpioIrqError>,
}

impl GpioIrqEvent {
    pub const fn none() -> Self {
        Self {
            source: None,
            lines: [GpioLineEvent::empty(); MAX_GPIO_IRQ_EVENTS],
            len: 0,
            error: None,
        }
    }

    pub fn from_line(line: GpioLineEvent) -> Self {
        let mut event = Self::none();
        let _ = event.push_line(line);
        event
    }

    pub const fn with_error(error: GpioIrqError) -> Self {
        Self {
            source: None,
            lines: [GpioLineEvent::empty(); MAX_GPIO_IRQ_EVENTS],
            len: 0,
            error: Some(error),
        }
    }

    pub const fn source(&self) -> Option<GpioIrqSourceId> {
        self.source
    }

    pub fn set_source(&mut self, source: GpioIrqSourceId) {
        self.source = Some(source);
    }

    pub fn push_line(&mut self, line: GpioLineEvent) -> bool {
        if self.len == self.lines.len() {
            self.error = Some(GpioIrqError::Overflow);
            return false;
        }
        self.lines[self.len] = line;
        self.len += 1;
        true
    }

    pub fn lines(&self) -> &[GpioLineEvent] {
        &self.lines[..self.len]
    }

    pub const fn error(&self) -> Option<GpioIrqError> {
        self.error
    }

    pub const fn is_empty(&self) -> bool {
        self.len == 0 && self.error.is_none()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GpioIrqSourceInfo {
    pub id: GpioIrqSourceId,
    pub lines: alloc::vec::Vec<GpioLineId>,
}

impl GpioIrqSourceInfo {
    pub fn new(id: GpioIrqSourceId, lines: alloc::vec::Vec<GpioLineId>) -> Self {
        Self { id, lines }
    }
}

pub trait GpioIrqHandler: Send + 'static {
    fn handle_irq(&mut self) -> GpioIrqEvent;
}