diff --git a/src/lib.rs b/src/lib.rs index a86bce1..c937edd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,13 +6,15 @@ extern crate embedded_hal as hal; extern crate embedded_graphics; use hal::blocking::delay::DelayMs; -use hal::blocking::spi; +use hal::blocking::spi::{Write, Transfer}; use hal::digital::v2::OutputPin; -use hal::spi::{Mode, Phase, Polarity}; use core::fmt::Debug; use core::iter::IntoIterator; +pub mod spi; +use spi::SpiInterface; + /// Trait representing the interface to the hardware. /// /// Intended to abstract the various buses (SPI, MPU 8/9/16-bit) from the Controller code. @@ -31,12 +33,6 @@ pub trait Interface { fn write_iter(&mut self, command: u8, data: impl IntoIterator) -> Result<(), Self::Error>; } -/// SPI mode -pub const MODE: Mode = Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnFirstTransition, -}; - const WIDTH: usize = 240; const HEIGHT: usize = 320; @@ -71,9 +67,7 @@ pub enum Orientation { /// and the next word will fill the next pixel (the adjacent on the right, or /// the first of the next row if the row ended) pub struct Ili9341 { - spi: SPI, - cs: CS, - dc: DC, + interface: SpiInterface, reset: RESET, width: usize, height: usize, @@ -81,7 +75,7 @@ pub struct Ili9341 { impl Ili9341 where - SPI: spi::Transfer + spi::Write, + SPI: Transfer + Write, CS: OutputPin, DC: OutputPin, RESET: OutputPin, @@ -93,10 +87,9 @@ where reset: RESET, delay: &mut DELAY, ) -> Result> { + let interface = SpiInterface::new(spi, cs, dc); let mut ili9341 = Ili9341 { - spi, - cs, - dc, + interface, reset, width: WIDTH, height: HEIGHT, @@ -159,51 +152,16 @@ where Ok(()) } fn command(&mut self, cmd: Command, args: &[u8]) -> Result<(), Error> { - self.cs.set_low().map_err(Error::OutputPin)?; - - self.dc.set_low().map_err(Error::OutputPin)?; - self.spi.write(&[cmd as u8]).map_err(Error::Spi)?; - - self.dc.set_high().map_err(Error::OutputPin)?; - self.spi.write(args).map_err(Error::Spi)?; - - self.cs.set_high().map_err(Error::OutputPin)?; - Ok(()) + self.interface.write(cmd as u8, args) } fn write_iter>( &mut self, data: I, ) -> Result<(), Error> { - self.cs.set_low().map_err(Error::OutputPin)?; - - self.dc.set_low().map_err(Error::OutputPin)?; - self.spi - .write(&[Command::MemoryWrite as u8]) - .map_err(Error::Spi)?; - - self.dc.set_high().map_err(Error::OutputPin)?; - for d in data.into_iter() { - self.spi - .write(&[(d >> 8) as u8, (d & 0xff) as u8]) - .map_err(Error::Spi)?; - } - - self.cs.set_high().map_err(Error::OutputPin)?; - Ok(()) + self.interface.write_iter(Command::MemoryWrite as u8, data) } fn write_raw(&mut self, data: &[u8]) -> Result<(), Error> { - self.cs.set_low().map_err(Error::OutputPin)?; - - self.dc.set_low().map_err(Error::OutputPin)?; - self.spi - .write(&[Command::MemoryWrite as u8]) - .map_err(Error::Spi)?; - - self.dc.set_high().map_err(Error::OutputPin)?; - self.spi.write(data).map_err(Error::Spi)?; - - self.cs.set_high().map_err(Error::OutputPin)?; - Ok(()) + self.interface.write(Command::MemoryWrite as u8, data) } fn set_window(&mut self, x0: u16, y0: u16, x1: u16, y1: u16) -> Result<(), Error> { self.command( @@ -310,7 +268,7 @@ use embedded_graphics::{drawable::Pixel, pixelcolor::Rgb565, Drawing}; #[cfg(feature = "graphics")] impl Drawing for Ili9341 where - SPI: spi::Transfer + spi::Write, + SPI: Transfer + Write, CS: OutputPin, DC: OutputPin, RESET: OutputPin, diff --git a/src/spi.rs b/src/spi.rs new file mode 100644 index 0000000..8eac1a2 --- /dev/null +++ b/src/spi.rs @@ -0,0 +1,67 @@ +use super::hal::blocking::spi; +use super::hal::spi::{Mode, Phase, Polarity}; +use super::hal::digital::v2::OutputPin; +use super::{Interface, Error}; + +/// SPI mode +pub const MODE: Mode = Mode { + polarity: Polarity::IdleLow, + phase: Phase::CaptureOnFirstTransition, +}; + +/// `Interface` implementation for SPI interfaces +pub struct SpiInterface { + spi: SPI, + cs: CS, + dc: DC, +} + +impl SpiInterface + where SPI: spi::Transfer + spi::Write, + CS: OutputPin, + DC: OutputPin, +{ + pub fn new(spi: SPI, cs: CS, dc: DC) -> Self { + Self { + spi, + cs, + dc, + } + } +} + +impl Interface for SpiInterface + where SPI: spi::Transfer + spi::Write, + CS: OutputPin, + DC: OutputPin, +{ + type Error = Error; + + fn write(&mut self, command: u8, data: &[u8]) -> Result<(), Self::Error> { + self.cs.set_low().map_err(Error::OutputPin)?; + + self.dc.set_low().map_err(Error::OutputPin)?; + self.spi.write(&[command]).map_err(Error::Spi)?; + + self.dc.set_high().map_err(Error::OutputPin)?; + self.spi.write(data).map_err(Error::Spi)?; + + self.cs.set_high().map_err(Error::OutputPin)?; + Ok(()) + } + + fn write_iter(&mut self, command: u8, data: impl IntoIterator) -> Result<(), Self::Error> { + self.cs.set_low().map_err(Error::OutputPin)?; + + self.dc.set_low().map_err(Error::OutputPin)?; + self.spi.write(&[command]).map_err(Error::Spi)?; + + self.dc.set_high().map_err(Error::OutputPin)?; + for w in data.into_iter() { + self.spi.write(&w.to_be_bytes()).map_err(Error::Spi)?; + } + + self.cs.set_high().map_err(Error::OutputPin)?; + Ok(()) + } +}