diff --git a/src/spi.rs b/src/spi.rs index 4f5798635..7ddb23fea 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -57,11 +57,13 @@ mod clock; mod instances; +mod interrupts; mod peripheral; pub use self::{ clock::{Clock, ClockSource}, instances::Instance, + interrupts::Interrupts, peripheral::SPI, }; diff --git a/src/spi/interrupts.rs b/src/spi/interrupts.rs new file mode 100644 index 000000000..9f45bf44a --- /dev/null +++ b/src/spi/interrupts.rs @@ -0,0 +1,69 @@ +use super::Instance; + +macro_rules! interrupts { + ( + $( + $doc:expr, + $field:ident, + $reg_field:ident; + )* + ) => { + /// Used to enable or disable SPI interrupts + /// + /// See [`SPI::enable_interrupts`] or [`SPI::disable_interrupts`]. + /// + /// [`SPI::enable_interrupts`]: struct.SPI.html#method.enable_interrupts + /// [`SPI::disable_interrupts`]: struct.SPI.html#method.disable_interrupts + pub struct Interrupts { + $( + #[doc = $doc] + pub $field: bool, + )* + } + + impl Interrupts { + pub(super) fn enable(&self, spi: &I) { + spi.intenset.write(|w| { + $( + if self.$field { + w.$reg_field().set_bit(); + } + )* + + w + }) + } + + pub(super) fn disable(&self, spi: &I) { + spi.intenclr.write(|w| { + $( + if self.$field { + w.$reg_field().set_bit(); + } + )* + + w + }) + } + } + + impl Default for Interrupts { + fn default() -> Self { + Self { + $( + $field: false, + )* + } + } + } + }; +} + +interrupts!( + "RX Ready", rx_ready, rxrdyen; + "TX Ready", tx_ready, txrdyen; + "Receiver Overrun", rx_overrun, rxoven; + "Transmitter Underrun", tx_underrun, txuren; + "Slave Select Asserted", slave_select_asserted, ssaen; + "Slave Select Deasserted", slave_select_deasserted, ssden; +); diff --git a/src/spi/peripheral.rs b/src/spi/peripheral.rs index 02bca213a..9f75438fd 100644 --- a/src/spi/peripheral.rs +++ b/src/spi/peripheral.rs @@ -8,7 +8,7 @@ use crate::{ syscon, }; -use super::{Clock, ClockSource, Instance}; +use super::{Clock, ClockSource, Instance, Interrupts}; /// Interface to a SPI peripheral /// @@ -124,6 +124,22 @@ impl SPI where I: Instance, { + /// Enable interrupts + /// + /// Enables all interrupts set to `true` in `interrupts`. Interrupts set to + /// `false` are not affected. + pub fn enable_interrupts(&mut self, interrupts: Interrupts) { + interrupts.enable(&self.spi); + } + + /// Disable interrupts + /// + /// Disables all interrupts set to `true` in `interrupts`. Interrupts set to + /// `false` are not affected. + pub fn disable_interrupts(&mut self, interrupts: Interrupts) { + interrupts.disable(&self.spi); + } + /// Disable the SPI peripheral /// /// This method is only available, if `SPI` is in the [`Enabled`] state.