lpc55-hal 0.3.0

Hardware Abstraction Layer (HAL) for the NXP LPC55S6x ARM Cortex-33 microcontrollers
Documentation
use core::ops::Deref;
use crate::{
    raw,
    peripherals::{
        syscon,
        inputmux::InputMux,
    },
    drivers::{
        pins::Pin,
    },
    typestates::{
        init_state,
        pin::{
            PinId,
            state,
            gpio::{
                direction,
            }
        },
 
    },
};

pub enum Mode {
    RisingEdge,
    FallingEdge,
    ActiveLow,
    ActiveHigh,
}

/// Bit position 0 - 7 indicating which of the 8 external interrupt positions to use
#[repr(u8)]
#[derive(Copy, Clone, Debug)]
pub enum Slot {
    Slot0 = 0,
    Slot1 = 1,
    Slot2 = 2,
    Slot3 = 3,
    Slot4 = 4,
    Slot5 = 5,
    Slot6 = 6,
    Slot7 = 7,
}

use Mode::*;

impl<State> Deref for Pint<State> {
    type Target = raw::pint::RegisterBlock;
    fn deref(&self) -> &Self::Target {
        &self.raw
    }
}

crate::wrap_stateful_peripheral!(Pint, PINT);

impl<State> Pint<State> {
    pub fn enabled(mut self, syscon: &mut syscon::Syscon) -> Pint<init_state::Enabled> {
        syscon.enable_clock(&mut self.raw);

        Pint {
            raw: self.raw,
            _state: init_state::Enabled(()),
        }
    }

    pub fn disabled(mut self, syscon: &mut syscon::Syscon) -> Pint<init_state::Disabled> {
        syscon.disable_clock(&mut self.raw);

        Pint {
            raw: self.raw,
            _state: init_state::Disabled,
        }
    }

}

impl Pint <init_state::Enabled> {

    /// LPC55 supports 8 external pin interrupts, from any PIO pin.
    /// Use `slot` to indicate (0-7) which slot you'd like to use.
    /// `mode` indicates what kind of interrupt to generate.
    /// You can call this function twice to enable both `RisingEdge` and `FallingEdge` interrupts for same pin + slot.
    pub fn enable_interrupt<PIN: PinId>(
        &mut self, 
        mux: &mut InputMux<init_state::Enabled>, 
        _pin:  &Pin<PIN, state::Gpio<direction::Input>>, 
        slot: Slot,
        mode: Mode
    ){

        // Enable pin as external interrupt for ext int source `slot`
        mux.raw.pintsel[slot as usize].write(|w| unsafe {
            w
            .intpin().bits( (PIN::PORT << 5) as u8 | (PIN::NUMBER) )
        });

        let bit = 1 << (slot as u8);

        // Clear respective slot bit (default rising)
        self.raw.isel.modify(|r,w| unsafe {
            w.pmode().bits(
                r.pmode().bits() & (!bit)
            )
        });

        match mode {
            RisingEdge => {
                // enable level/rising interrupt
                self.raw.sienr.write(|w| unsafe {
                    w.setenrl().bits( bit )
                });
            }
            FallingEdge => {
                // enable falling interrupt
                self.raw.sienf.write(|w| unsafe {
                    w.setenaf().bits( bit )
                });
            }
            _ => {

                // Make level interrupt
                self.raw.isel.modify(|r,w| unsafe {
                    w.pmode().bits(
                        r.pmode().bits() | bit
                    )
                });

                // enable level/rising interrupt
                self.raw.sienr.write(|w| unsafe {
                    w.setenrl().bits( bit )
                });

                match mode {
                    ActiveHigh => {
                        // Make level active high
                        self.raw.sienf.write(|w| unsafe {
                            w.setenaf().bits( bit )
                        });  
                    }
                    ActiveLow => {
                        // Make level active low
                        self.raw.cienf.write(|w| unsafe {
                            w.cenaf().bits( bit )
                        });  

                    }
                    _ => {}
                }


            }
        }

    }
}