Merge pull request #25 from GrantM11235/display-error

Use `display_interface::DisplayError`
This commit is contained in:
Yuri Iozzelli 2021-05-11 20:24:46 +02:00 committed by GitHub
commit 510d0c9a03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 48 deletions

View file

@ -11,7 +11,7 @@ edition = "2018"
[dependencies] [dependencies]
display-interface = "0.4.0" display-interface = "0.4.1"
embedded-hal = "0.2.4" embedded-hal = "0.2.4"
[dependencies.embedded-graphics] [dependencies.embedded-graphics]

View file

@ -1,6 +1,6 @@
use crate::{Ili9341, OutputPin}; use crate::Ili9341;
use core::{fmt::Debug, iter}; use core::iter;
use embedded_graphics::{ use embedded_graphics::{
drawable::Pixel, drawable::Pixel,
@ -14,13 +14,11 @@ use embedded_graphics::{
DrawTarget, DrawTarget,
}; };
impl<PinE, IFACE, RESET> DrawTarget<Rgb565> for Ili9341<IFACE, RESET> impl<IFACE, RESET> DrawTarget<Rgb565> for Ili9341<IFACE, RESET>
where where
IFACE: display_interface::WriteOnlyDataCommand, IFACE: display_interface::WriteOnlyDataCommand,
RESET: OutputPin<Error = PinE>,
PinE: Debug,
{ {
type Error = crate::Error<PinE>; type Error = display_interface::DisplayError;
fn size(&self) -> Size { fn size(&self) -> Size {
Size::new(self.width as u32, self.height as u32) Size::new(self.width as u32, self.height as u32)

View file

@ -12,6 +12,10 @@ use display_interface::WriteOnlyDataCommand;
pub use embedded_hal::spi::MODE_0 as SPI_MODE; pub use embedded_hal::spi::MODE_0 as SPI_MODE;
pub use display_interface::DisplayError;
type Result<T = (), E = DisplayError> = core::result::Result<T, E>;
/// Trait that defines display size information /// Trait that defines display size information
pub trait DisplaySize { pub trait DisplaySize {
/// Width in pixels /// Width in pixels
@ -36,12 +40,6 @@ impl DisplaySize for DisplaySize320x480 {
const HEIGHT: usize = 480; const HEIGHT: usize = 480;
} }
#[derive(Debug)]
pub enum Error<PinE> {
Interface,
OutputPin(PinE),
}
/// The default orientation is Portrait /// The default orientation is Portrait
pub enum Orientation { pub enum Orientation {
Portrait, Portrait,
@ -74,10 +72,10 @@ pub struct Ili9341<IFACE, RESET> {
mode: Orientation, mode: Orientation,
} }
impl<PinE, IFACE, RESET> Ili9341<IFACE, RESET> impl<IFACE, RESET> Ili9341<IFACE, RESET>
where where
IFACE: WriteOnlyDataCommand, IFACE: WriteOnlyDataCommand,
RESET: OutputPin<Error = PinE>, RESET: OutputPin,
{ {
pub fn new<DELAY, SIZE>( pub fn new<DELAY, SIZE>(
interface: IFACE, interface: IFACE,
@ -85,7 +83,7 @@ where
delay: &mut DELAY, delay: &mut DELAY,
mode: Orientation, mode: Orientation,
_display_size: SIZE, _display_size: SIZE,
) -> Result<Self, Error<PinE>> ) -> Result<Self>
where where
DELAY: DelayMs<u16>, DELAY: DelayMs<u16>,
SIZE: DisplaySize, SIZE: DisplaySize,
@ -99,10 +97,13 @@ where
}; };
// Do hardware reset by holding reset low for at least 10us // Do hardware reset by holding reset low for at least 10us
ili9341.reset.set_low().map_err(Error::OutputPin)?; ili9341.reset.set_low().map_err(|_| DisplayError::RSError)?;
delay.delay_ms(1); delay.delay_ms(1);
// Set high for normal operation // Set high for normal operation
ili9341.reset.set_high().map_err(Error::OutputPin)?; ili9341
.reset
.set_high()
.map_err(|_| DisplayError::RSError)?;
// Wait 5ms after reset before sending commands // Wait 5ms after reset before sending commands
// and 120ms before sending Sleep Out // and 120ms before sending Sleep Out
@ -129,24 +130,23 @@ where
Ok(ili9341) Ok(ili9341)
} }
fn command(&mut self, cmd: Command, args: &[u8]) -> Result<(), Error<PinE>> {
self.interface
.send_commands(U8Iter(&mut once(cmd as u8)))
.map_err(|_| Error::Interface)?;
self.interface
.send_data(U8Iter(&mut args.iter().cloned()))
.map_err(|_| Error::Interface)
} }
fn write_iter<I: IntoIterator<Item = u16>>(&mut self, data: I) -> Result<(), Error<PinE>> { impl<IFACE, RESET> Ili9341<IFACE, RESET>
where
IFACE: WriteOnlyDataCommand,
{
fn command(&mut self, cmd: Command, args: &[u8]) -> Result {
self.interface.send_commands(U8Iter(&mut once(cmd as u8)))?;
self.interface.send_data(U8Iter(&mut args.iter().cloned()))
}
fn write_iter<I: IntoIterator<Item = u16>>(&mut self, data: I) -> Result {
self.command(Command::MemoryWrite, &[])?; self.command(Command::MemoryWrite, &[])?;
self.interface self.interface.send_data(U16BEIter(&mut data.into_iter()))
.send_data(U16BEIter(&mut data.into_iter()))
.map_err(|_| Error::Interface)
} }
fn set_window(&mut self, x0: u16, y0: u16, x1: u16, y1: u16) -> Result<(), Error<PinE>> { fn set_window(&mut self, x0: u16, y0: u16, x1: u16, y1: u16) -> Result {
self.command( self.command(
Command::ColumnAddressSet, Command::ColumnAddressSet,
&[ &[
@ -164,8 +164,7 @@ where
(y1 >> 8) as u8, (y1 >> 8) as u8,
(y1 & 0xff) as u8, (y1 & 0xff) as u8,
], ],
)?; )
Ok(())
} }
/// Configures the screen for hardware-accelerated vertical scrolling. /// Configures the screen for hardware-accelerated vertical scrolling.
@ -173,7 +172,7 @@ where
&mut self, &mut self,
fixed_top_lines: u16, fixed_top_lines: u16,
fixed_bottom_lines: u16, fixed_bottom_lines: u16,
) -> Result<Scroller, Error<PinE>> { ) -> Result<Scroller> {
let height = match self.mode { let height = match self.mode {
Orientation::Landscape | Orientation::LandscapeFlipped => self.width, Orientation::Landscape | Orientation::LandscapeFlipped => self.width,
Orientation::Portrait | Orientation::PortraitFlipped => self.height, Orientation::Portrait | Orientation::PortraitFlipped => self.height,
@ -195,11 +194,7 @@ where
Ok(Scroller::new(fixed_top_lines, fixed_bottom_lines, height)) Ok(Scroller::new(fixed_top_lines, fixed_bottom_lines, height))
} }
pub fn scroll_vertically( pub fn scroll_vertically(&mut self, scroller: &mut Scroller, num_lines: u16) -> Result {
&mut self,
scroller: &mut Scroller,
num_lines: u16,
) -> Result<(), Error<PinE>> {
scroller.top_offset += num_lines; scroller.top_offset += num_lines;
if scroller.top_offset > (scroller.height - scroller.fixed_bottom_lines) { if scroller.top_offset > (scroller.height - scroller.fixed_bottom_lines) {
scroller.top_offset = scroller.fixed_top_lines scroller.top_offset = scroller.fixed_top_lines
@ -231,7 +226,7 @@ where
x1: u16, x1: u16,
y1: u16, y1: u16,
data: I, data: I,
) -> Result<(), Error<PinE>> { ) -> Result {
self.set_window(x0, y0, x1, y1)?; self.set_window(x0, y0, x1, y1)?;
self.write_iter(data) self.write_iter(data)
} }
@ -245,20 +240,13 @@ where
/// video memory. /// video memory.
/// ///
/// The expected format is rgb565. /// The expected format is rgb565.
pub fn draw_raw( pub fn draw_raw(&mut self, x0: u16, y0: u16, x1: u16, y1: u16, data: &[u16]) -> Result {
&mut self,
x0: u16,
y0: u16,
x1: u16,
y1: u16,
data: &[u16],
) -> Result<(), Error<PinE>> {
self.set_window(x0, y0, x1, y1)?; self.set_window(x0, y0, x1, y1)?;
self.write_iter(data.iter().cloned()) self.write_iter(data.iter().cloned())
} }
/// Change the orientation of the screen /// Change the orientation of the screen
pub fn set_orientation(&mut self, mode: Orientation) -> Result<(), Error<PinE>> { pub fn set_orientation(&mut self, mode: Orientation) -> Result {
let was_landscape = match self.mode { let was_landscape = match self.mode {
Orientation::Landscape | Orientation::LandscapeFlipped => true, Orientation::Landscape | Orientation::LandscapeFlipped => true,
Orientation::Portrait | Orientation::PortraitFlipped => false, Orientation::Portrait | Orientation::PortraitFlipped => false,
@ -287,7 +275,9 @@ where
self.mode = mode; self.mode = mode;
Ok(()) Ok(())
} }
}
impl<IFACE, RESET> Ili9341<IFACE, RESET> {
/// Get the current screen width. It can change based on the current orientation /// Get the current screen width. It can change based on the current orientation
pub fn width(&self) -> usize { pub fn width(&self) -> usize {
self.width self.width