From 45e3f8d2b5dd3cc855cffedb6abf4d877cffb550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 11 Jun 2020 21:53:39 +0200 Subject: [PATCH 01/21] Sketch up type-level display size --- Cargo.toml | 1 + src/builder.rs | 33 +++++++++------ src/displaysize.rs | 92 ++++++++++++++++++++++++++++++----------- src/mode/displaymode.rs | 6 +-- src/mode/graphics.rs | 39 +++++++++-------- src/mode/terminal.rs | 77 +++++++++++++++++++++------------- src/properties.rs | 57 ++++++++----------------- 7 files changed, 180 insertions(+), 125 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bdd364b1..1fd52abb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ embedded-hal = "0.2.3" display-interface = "0.4" display-interface-i2c = "0.4" display-interface-spi = "0.4" +typenum = "1.12.0" [dependencies.embedded-graphics] optional = true diff --git a/src/builder.rs b/src/builder.rs index 04e6719d..09b71433 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -59,36 +59,45 @@ use display_interface::WriteOnlyDataCommand; use crate::{ - displayrotation::DisplayRotation, displaysize::DisplaySize, properties::DisplayProperties, + displayrotation::DisplayRotation, displaysize::*, properties::DisplayProperties, }; /// Builder struct. Driver options and interface are set using its methods. #[derive(Clone, Copy)] -pub struct Builder { - display_size: DisplaySize, +pub struct Builder +where + DSIZE: DisplaySize +{ rotation: DisplayRotation, + _size: core::marker::PhantomData, } -impl Default for Builder { +impl Default for Builder +where + DSIZE: DisplaySize, +{ fn default() -> Self { Self::new() } } -impl Builder { +impl Builder +where + DSIZE: DisplaySize +{ /// Create new builder with a default size of 128 x 64 pixels and no rotation. pub fn new() -> Self { Self { - display_size: DisplaySize::Display128x64, rotation: DisplayRotation::Rotate0, + _size: core::marker::PhantomData, } } /// Set the size of the display. Supported sizes are defined by [DisplaySize]. - pub fn size(self, display_size: DisplaySize) -> Self { - Self { - display_size, - ..self + pub fn size(self) -> Builder { + Builder { + rotation: self.rotation, + _size: core::marker::PhantomData, } } @@ -102,11 +111,11 @@ impl Builder { /// Finish the builder and use some interface communicate with the display /// /// This method consumes the builder and must come last in the method call chain - pub fn connect(self, interface: I) -> DisplayProperties + pub fn connect(self, interface: I) -> DisplayProperties where I: WriteOnlyDataCommand, { - DisplayProperties::new(interface, self.display_size, self.rotation) + DisplayProperties::new(interface, self.rotation) } } diff --git a/src/displaysize.rs b/src/displaysize.rs index 9b59fc29..6a670fa1 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -1,31 +1,73 @@ //! Display size -// TODO: Add to prelude -/// Display size enumeration -#[derive(Clone, Copy)] -pub enum DisplaySize { - /// 128 by 64 pixels - Display128x64, - /// 128 by 32 pixels - Display128x32, - /// 96 by 16 pixels - Display96x16, - /// 70 by 42 pixels - Display72x40, - /// 64 by 48 pixels - Display64x48, +use super::command::Command; +use typenum::{Unsigned, U0, U16, U28, U32, U40, U48, U64, U72, U96, U128}; + +pub trait DisplaySize { + type Width: Unsigned; + type Height: Unsigned; + type OffsetX: Unsigned; + type OffsetY: Unsigned; + + fn ComPinConfig() -> Command; +} + +pub struct DisplaySize128x64; +impl DisplaySize for DisplaySize128x64 { + type Width = U128; + type Height = U64; + type OffsetX = U0; + type OffsetY = U0; + + fn ComPinConfig() -> Command { + Command::ComPinConfig(true, false) + } +} + +pub struct DisplaySize128x32; +impl DisplaySize for DisplaySize128x32 { + type Width = U128; + type Height = U32; + type OffsetX = U0; + type OffsetY = U0; + + fn ComPinConfig() -> Command { + Command::ComPinConfig(false, false) + } } -impl DisplaySize { - /// Get integral dimensions from DisplaySize - // TODO: Use whatever vec2 impl I decide to use here - pub fn dimensions(self) -> (u8, u8) { - match self { - DisplaySize::Display128x64 => (128, 64), - DisplaySize::Display128x32 => (128, 32), - DisplaySize::Display96x16 => (96, 16), - DisplaySize::Display72x40 => (72, 40), - DisplaySize::Display64x48 => (64, 48), - } +pub struct DisplaySize96x16; +impl DisplaySize for DisplaySize96x16 { + type Width = U96; + type Height = U16; + type OffsetX = U0; + type OffsetY = U0; + + fn ComPinConfig() -> Command { + Command::ComPinConfig(false, false) + } +} + +pub struct DisplaySize72x40; +impl DisplaySize for DisplaySize72x40 { + type Width = U72; + type Height = U40; + type OffsetX = U28; + type OffsetY = U0; + + fn ComPinConfig() -> Command { + Command::ComPinConfig(true, false) + } +} + +pub struct DisplaySize64x48; +impl DisplaySize for DisplaySize64x48 { + type Width = U64; + type Height = U48; + type OffsetX = U32; + type OffsetY = U0; + + fn ComPinConfig() -> Command { + Command::ComPinConfig(true, false) } } diff --git a/src/mode/displaymode.rs b/src/mode/displaymode.rs index a208da2c..31455452 100644 --- a/src/mode/displaymode.rs +++ b/src/mode/displaymode.rs @@ -5,12 +5,12 @@ use crate::Error; use hal::{blocking::delay::DelayMs, digital::v2::OutputPin}; /// Trait with core functionality for display mode switching -pub trait DisplayModeTrait: Sized { +pub trait DisplayModeTrait: Sized { /// Allocate all required data and initialise display for mode - fn new(properties: DisplayProperties) -> Self; + fn new(properties: DisplayProperties) -> Self; /// Deconstruct object and retrieve DisplayProperties - fn into_properties(self) -> DisplayProperties; + fn into_properties(self) -> DisplayProperties; /// Release display interface fn release(self) -> DI { diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index 7484ad92..e81fa995 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -55,6 +55,8 @@ //! //! [embedded_graphics]: https://crates.io/crates/embedded_graphics +use typenum::Unsigned; +use crate::displaysize::DisplaySize; use display_interface::{DisplayError, WriteOnlyDataCommand}; use crate::{ @@ -64,8 +66,11 @@ use crate::{ // TODO: Add to prelude /// Graphics mode handler -pub struct GraphicsMode { - properties: DisplayProperties, +pub struct GraphicsMode +where + DSIZE: DisplaySize, +{ + properties: DisplayProperties, buffer: [u8; 1024], min_x: u8, max_x: u8, @@ -73,9 +78,12 @@ pub struct GraphicsMode { max_y: u8, } -impl DisplayModeTrait for GraphicsMode { +impl DisplayModeTrait for GraphicsMode +where + DSIZE: DisplaySize, +{ /// Create new GraphicsMode instance - fn new(properties: DisplayProperties) -> Self { + fn new(properties: DisplayProperties) -> Self { GraphicsMode { properties, buffer: [0; 1024], @@ -87,13 +95,14 @@ impl DisplayModeTrait for GraphicsMode { } /// Release display interface used by `GraphicsMode` - fn into_properties(self) -> DisplayProperties { + fn into_properties(self) -> DisplayProperties { self.properties } } impl GraphicsMode where + DSIZE: DisplaySize, DI: WriteOnlyDataCommand, { /// Clear the display buffer. You need to call `disp.flush()` for any effect on the screen @@ -136,16 +145,12 @@ where self.min_y = width - 1; self.max_y = 0; - // Compensate for any offset in the physical display. For example, the 72x40 display has an - // offset of (28, 0) pixels. - let offs = self.properties.display_offset; - // Tell the display to update only the part that has changed match self.properties.get_rotation() { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { self.properties.set_draw_area( - (disp_min_x + offs.0, disp_min_y + offs.1), - (disp_max_x + offs.0, disp_max_y + offs.1), + (disp_min_x + DSIZE::OffsetX::U8, disp_min_y + DSIZE::OffsetY::U8), + (disp_max_x + DSIZE::OffsetX::U8, disp_max_y + DSIZE::OffsetY::U8), )?; self.properties.bounded_draw( @@ -157,8 +162,8 @@ where } DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { self.properties.set_draw_area( - (disp_min_y + offs.1, disp_min_x + offs.0), - (disp_max_y + offs.1, disp_max_x + offs.0), + (disp_min_y + DSIZE::OffsetY::U8, disp_min_x + DSIZE::OffsetX::U8), + (disp_max_y + DSIZE::OffsetY::U8, disp_max_x + DSIZE::OffsetX::U8), )?; self.properties.bounded_draw( @@ -174,18 +179,17 @@ where /// Turn a pixel on or off. A non-zero `value` is treated as on, `0` as off. If the X and Y /// coordinates are out of the bounds of the display, this method call is a noop. pub fn set_pixel(&mut self, x: u32, y: u32, value: u8) { - let (display_width, _) = self.properties.get_size().dimensions(); let display_rotation = self.properties.get_rotation(); let (idx, bit) = match display_rotation { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { - let idx = ((y as usize) / 8 * display_width as usize) + (x as usize); + let idx = ((y as usize) / 8 * DSIZE::Width::U8 as usize) + (x as usize); let bit = y % 8; (idx, bit) } DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { - let idx = ((x as usize) / 8 * display_width as usize) + (y as usize); + let idx = ((x as usize) / 8 * DSIZE::Width::U8 as usize) + (y as usize); let bit = x % 8; (idx, bit) @@ -247,9 +251,10 @@ use embedded_graphics::{ }; #[cfg(feature = "graphics")] -impl DrawTarget for GraphicsMode +impl DrawTarget for GraphicsMode where DI: WriteOnlyDataCommand, + DSIZE: DisplaySize, { type Error = DisplayError; diff --git a/src/mode/terminal.rs b/src/mode/terminal.rs index e83255d0..0244faf9 100644 --- a/src/mode/terminal.rs +++ b/src/mode/terminal.rs @@ -25,13 +25,14 @@ //! } //! ``` +use typenum::{Unsigned, U128, U64, U24, U45, U48}; use display_interface::{DisplayError, WriteOnlyDataCommand}; use crate::{ brightness::Brightness, command::AddrMode, displayrotation::DisplayRotation, - displaysize::DisplaySize, + displaysize::*, mode::{ displaymode::DisplayModeTrait, terminal::TerminalModeError::{InterfaceError, OutOfBounds, Uninitialized}, @@ -40,6 +41,30 @@ use crate::{ }; use core::{cmp::min, fmt}; +pub trait TerminalDisplaySize: DisplaySize { + type CharNum: Unsigned; +} + +impl TerminalDisplaySize for DisplaySize128x64 { + type CharNum = U128; +} + +impl TerminalDisplaySize for DisplaySize128x32 { + type CharNum = U64; +} + +impl TerminalDisplaySize for DisplaySize96x16 { + type CharNum = U24; +} + +impl TerminalDisplaySize for DisplaySize72x40 { + type CharNum = U45; +} + +impl TerminalDisplaySize for DisplaySize64x48 { + type CharNum = U48; +} + /// Contains the new row that the cursor has wrapped around to struct CursorWrapEvent(u8); @@ -135,17 +160,21 @@ impl IntoTerminalModeResult for Result { // TODO: Add to prelude /// Terminal mode handler -pub struct TerminalMode { - properties: DisplayProperties, +pub struct TerminalMode +where + DSIZE: TerminalDisplaySize, +{ + properties: DisplayProperties, cursor: Option, } -impl DisplayModeTrait for TerminalMode +impl DisplayModeTrait for TerminalMode where DI: WriteOnlyDataCommand, + DSIZE: TerminalDisplaySize, { /// Create new TerminalMode instance - fn new(properties: DisplayProperties) -> Self { + fn new(properties: DisplayProperties) -> Self { TerminalMode { properties, cursor: None, @@ -153,41 +182,32 @@ where } /// Release display interface used by `TerminalMode` - fn into_properties(self) -> DisplayProperties { + fn into_properties(self) -> DisplayProperties { self.properties } } impl TerminalMode where + DSIZE: TerminalDisplaySize, DI: WriteOnlyDataCommand, { /// Clear the display and reset the cursor to the top left corner pub fn clear(&mut self) -> Result<(), TerminalModeError> { - let display_size = self.properties.get_size(); - - // The number of characters that can fit on the display at once (w * h / 8 * 8) - // TODO: Use `display_size.dimensions()` - let numchars = match display_size { - DisplaySize::Display128x64 => 128, - DisplaySize::Display128x32 => 64, - DisplaySize::Display96x16 => 24, - DisplaySize::Display72x40 => 45, - DisplaySize::Display64x48 => 48, - }; + + // The number of characters that can fit on the display at once (w * h / (8 * 8)) + let numchars = DSIZE::CharNum::U8; // Let the chip handle line wrapping so we can fill the screen with blanks faster self.properties .change_mode(AddrMode::Horizontal) .terminal_err()?; - let (display_width, display_height) = self.properties.get_dimensions(); - let (display_x_offset, display_y_offset) = self.properties.display_offset; self.properties .set_draw_area( - (display_x_offset, display_y_offset), + (DSIZE::OffsetX::U8, DSIZE::OffsetY::U8), ( - display_width + display_x_offset, - display_height + display_y_offset, + DSIZE::Width::U8 + DSIZE::OffsetX::U8, + DSIZE::Height::U8 + DSIZE::OffsetY::U8, ), ) .terminal_err()?; @@ -236,7 +256,7 @@ where } /// Initialise the display in page mode (i.e. a byte walks down a column of 8 pixels) with - /// column 0 on the left and column _(display_width - 1)_ on the right, but no automatic line + /// column 0 on the left and column _(DSIZE::Width::U8 - 1)_ on the right, but no automatic line /// wrapping. pub fn init(&mut self) -> Result<(), TerminalModeError> { self.properties @@ -289,14 +309,12 @@ where /// Reset the draw area and move pointer to the top left corner fn reset_pos(&mut self) -> Result<(), TerminalModeError> { - let (display_x_offset, display_y_offset) = self.properties.display_offset; self.properties - .set_column(display_x_offset) + .set_column(DSIZE::OffsetX::U8) .terminal_err()?; - self.properties.set_row(display_y_offset).terminal_err()?; + self.properties.set_row(DSIZE::OffsetY::U8).terminal_err()?; // Initialise the counter when we know it's valid - let (display_width, display_height) = self.properties.get_dimensions(); - self.cursor = Some(Cursor::new(display_width, display_height)); + self.cursor = Some(Cursor::new(DSIZE::Width::U8, DSIZE::Height::U8)); Ok(()) } @@ -415,9 +433,10 @@ where } } -impl fmt::Write for TerminalMode +impl fmt::Write for TerminalMode where DI: WriteOnlyDataCommand, + DSIZE: TerminalDisplaySize, { fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { s.chars().map(move |c| self.print_char(c)).last(); diff --git a/src/properties.rs b/src/properties.rs index fafc753a..47578c80 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -1,5 +1,5 @@ //! Container to store and set display properties - +use typenum::Unsigned; use crate::mode::displaymode::DisplayModeTrait; use crate::{ brightness::Brightness, @@ -10,47 +10,42 @@ use crate::{ use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; /// Display properties struct -pub struct DisplayProperties { +pub struct DisplayProperties { iface: DI, - display_size: DisplaySize, display_rotation: DisplayRotation, - pub(crate) display_offset: (u8, u8), addr_mode: AddrMode, + _size: core::marker::PhantomData, } -impl DisplayProperties { +impl DisplayProperties +where + DSIZE: DisplaySize, +{ /// Create new DisplayProperties instance pub fn new( iface: DI, - display_size: DisplaySize, display_rotation: DisplayRotation, - ) -> DisplayProperties { - let display_offset = match display_size { - DisplaySize::Display128x64 => (0, 0), - DisplaySize::Display128x32 => (0, 0), - DisplaySize::Display96x16 => (0, 0), - DisplaySize::Display72x40 => (28, 0), - DisplaySize::Display64x48 => (32, 0), - }; - + ) -> DisplayProperties { DisplayProperties { iface, - display_size, display_rotation, - display_offset, addr_mode: AddrMode::Page, // reset value + _size: core::marker::PhantomData, } } +} +impl DisplayProperties { /// Releases the display interface pub fn release(self) -> DI { self.iface } } -impl DisplayProperties +impl DisplayProperties where DI: WriteOnlyDataCommand, + DSIZE: DisplaySize, { /// Initialise the display in column mode (i.e. a byte walks down a column of 8 pixels) with /// column 0 on the left and column _(display_width - 1)_ on the right. @@ -60,14 +55,11 @@ where /// Initialise the display in one of the available addressing modes pub fn init_with_mode(&mut self, mode: AddrMode) -> Result<(), DisplayError> { - // TODO: Break up into nice bits so display modes can pick whathever they need - let (_, display_height) = self.display_size.dimensions(); - let display_rotation = self.display_rotation; Command::DisplayOn(false).send(&mut self.iface)?; Command::DisplayClockDiv(0x8, 0x0).send(&mut self.iface)?; - Command::Multiplex(display_height - 1).send(&mut self.iface)?; + Command::Multiplex(DSIZE::Height::U8 - 1).send(&mut self.iface)?; Command::DisplayOffset(0).send(&mut self.iface)?; Command::StartLine(0).send(&mut self.iface)?; // TODO: Ability to turn charge pump on/off @@ -76,13 +68,7 @@ where self.set_rotation(display_rotation)?; - match self.display_size { - DisplaySize::Display128x32 => Command::ComPinConfig(false, false).send(&mut self.iface), - DisplaySize::Display128x64 => Command::ComPinConfig(true, false).send(&mut self.iface), - DisplaySize::Display96x16 => Command::ComPinConfig(false, false).send(&mut self.iface), - DisplaySize::Display72x40 => Command::ComPinConfig(true, false).send(&mut self.iface), - DisplaySize::Display64x48 => Command::ComPinConfig(true, false).send(&mut self.iface), - }?; + DSIZE::ComPinConfig().send(&mut self.iface)?; self.set_brightness(Brightness::default())?; Command::VcomhDeselect(VcomhLevel::Auto).send(&mut self.iface)?; @@ -178,11 +164,6 @@ where .try_for_each(|c| self.iface.send_data(U8(&c))) } - /// Get the configured display size - pub fn get_size(&self) -> DisplaySize { - self.display_size - } - /// Get display dimensions, taking into account the current rotation of the display /// /// ```rust @@ -206,11 +187,9 @@ where /// assert_eq!(rotated_disp.get_dimensions(), (64, 128)); /// ``` pub fn get_dimensions(&self) -> (u8, u8) { - let (w, h) = self.display_size.dimensions(); - match self.display_rotation { - DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => (w, h), - DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => (h, w), + DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => (DSIZE::Width::U8, DSIZE::Height::U8), + DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => (DSIZE::Height::U8, DSIZE::Width::U8), } } @@ -264,7 +243,7 @@ where } /// Change into any mode implementing DisplayModeTrait - pub fn into>(self) -> NMODE + pub fn into>(self) -> NMODE where DI: WriteOnlyDataCommand, { From 9221aa98529f49f838ae82ce0ee769831f988ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 11 Jun 2020 22:48:02 +0200 Subject: [PATCH 02/21] Use display buffers with only the necessary size --- Cargo.toml | 1 + src/displaysize.rs | 9 ++++++++- src/mode/graphics.rs | 7 ++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1fd52abb..4235315a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ display-interface = "0.4" display-interface-i2c = "0.4" display-interface-spi = "0.4" typenum = "1.12.0" +generic-array = "0.14.2" [dependencies.embedded-graphics] optional = true diff --git a/src/displaysize.rs b/src/displaysize.rs index 6a670fa1..fd218574 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -1,13 +1,15 @@ //! Display size +use generic_array::ArrayLength; use super::command::Command; -use typenum::{Unsigned, U0, U16, U28, U32, U40, U48, U64, U72, U96, U128}; +use typenum::{Unsigned, U0, U16, U28, U32, U40, U48, U64, U72, U96, U128, U192, U360, U384, U512, U1024}; pub trait DisplaySize { type Width: Unsigned; type Height: Unsigned; type OffsetX: Unsigned; type OffsetY: Unsigned; + type BufferSize: ArrayLength; fn ComPinConfig() -> Command; } @@ -18,6 +20,7 @@ impl DisplaySize for DisplaySize128x64 { type Height = U64; type OffsetX = U0; type OffsetY = U0; + type BufferSize = U1024; fn ComPinConfig() -> Command { Command::ComPinConfig(true, false) @@ -30,6 +33,7 @@ impl DisplaySize for DisplaySize128x32 { type Height = U32; type OffsetX = U0; type OffsetY = U0; + type BufferSize = U512; fn ComPinConfig() -> Command { Command::ComPinConfig(false, false) @@ -42,6 +46,7 @@ impl DisplaySize for DisplaySize96x16 { type Height = U16; type OffsetX = U0; type OffsetY = U0; + type BufferSize = U192; fn ComPinConfig() -> Command { Command::ComPinConfig(false, false) @@ -54,6 +59,7 @@ impl DisplaySize for DisplaySize72x40 { type Height = U40; type OffsetX = U28; type OffsetY = U0; + type BufferSize = U360; fn ComPinConfig() -> Command { Command::ComPinConfig(true, false) @@ -66,6 +72,7 @@ impl DisplaySize for DisplaySize64x48 { type Height = U48; type OffsetX = U32; type OffsetY = U0; + type BufferSize = U384; fn ComPinConfig() -> Command { Command::ComPinConfig(true, false) diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index e81fa995..a0846498 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -55,6 +55,7 @@ //! //! [embedded_graphics]: https://crates.io/crates/embedded_graphics +use generic_array::GenericArray; use typenum::Unsigned; use crate::displaysize::DisplaySize; use display_interface::{DisplayError, WriteOnlyDataCommand}; @@ -71,7 +72,7 @@ where DSIZE: DisplaySize, { properties: DisplayProperties, - buffer: [u8; 1024], + buffer: GenericArray, min_x: u8, max_x: u8, min_y: u8, @@ -86,7 +87,7 @@ where fn new(properties: DisplayProperties) -> Self { GraphicsMode { properties, - buffer: [0; 1024], + buffer: GenericArray::default(), min_x: 255, max_x: 0, min_y: 255, @@ -107,7 +108,7 @@ where { /// Clear the display buffer. You need to call `disp.flush()` for any effect on the screen pub fn clear(&mut self) { - self.buffer = [0; 1024]; + self.buffer = GenericArray::default(); let (width, height) = self.get_dimensions(); self.min_x = 0; From cd9e24deeca2e8de3423dc8f2ba8fa2bc13cf870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Thu, 11 Jun 2020 22:50:55 +0200 Subject: [PATCH 03/21] Run cargo fmt --- src/builder.rs | 10 ++++------ src/displaysize.rs | 6 ++++-- src/mode/graphics.rs | 25 +++++++++++++++++++------ src/mode/terminal.rs | 3 +-- src/properties.rs | 17 +++++++++-------- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 09b71433..f1f945aa 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -58,15 +58,13 @@ use display_interface::WriteOnlyDataCommand; -use crate::{ - displayrotation::DisplayRotation, displaysize::*, properties::DisplayProperties, -}; +use crate::{displayrotation::DisplayRotation, displaysize::*, properties::DisplayProperties}; /// Builder struct. Driver options and interface are set using its methods. #[derive(Clone, Copy)] -pub struct Builder +pub struct Builder where - DSIZE: DisplaySize + DSIZE: DisplaySize, { rotation: DisplayRotation, _size: core::marker::PhantomData, @@ -83,7 +81,7 @@ where impl Builder where - DSIZE: DisplaySize + DSIZE: DisplaySize, { /// Create new builder with a default size of 128 x 64 pixels and no rotation. pub fn new() -> Self { diff --git a/src/displaysize.rs b/src/displaysize.rs index fd218574..866b6f47 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -1,8 +1,10 @@ //! Display size -use generic_array::ArrayLength; use super::command::Command; -use typenum::{Unsigned, U0, U16, U28, U32, U40, U48, U64, U72, U96, U128, U192, U360, U384, U512, U1024}; +use generic_array::ArrayLength; +use typenum::{ + Unsigned, U0, U1024, U128, U16, U192, U28, U32, U360, U384, U40, U48, U512, U64, U72, U96, +}; pub trait DisplaySize { type Width: Unsigned; diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index a0846498..781b5853 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -55,10 +55,11 @@ //! //! [embedded_graphics]: https://crates.io/crates/embedded_graphics -use generic_array::GenericArray; -use typenum::Unsigned; use crate::displaysize::DisplaySize; use display_interface::{DisplayError, WriteOnlyDataCommand}; +use generic_array::GenericArray; +use hal::{blocking::delay::DelayMs, digital::v2::OutputPin}; +use typenum::Unsigned; use crate::{ brightness::Brightness, displayrotation::DisplayRotation, mode::displaymode::DisplayModeTrait, @@ -150,8 +151,14 @@ where match self.properties.get_rotation() { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { self.properties.set_draw_area( - (disp_min_x + DSIZE::OffsetX::U8, disp_min_y + DSIZE::OffsetY::U8), - (disp_max_x + DSIZE::OffsetX::U8, disp_max_y + DSIZE::OffsetY::U8), + ( + disp_min_x + DSIZE::OffsetX::U8, + disp_min_y + DSIZE::OffsetY::U8, + ), + ( + disp_max_x + DSIZE::OffsetX::U8, + disp_max_y + DSIZE::OffsetY::U8, + ), )?; self.properties.bounded_draw( @@ -163,8 +170,14 @@ where } DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { self.properties.set_draw_area( - (disp_min_y + DSIZE::OffsetY::U8, disp_min_x + DSIZE::OffsetX::U8), - (disp_max_y + DSIZE::OffsetY::U8, disp_max_x + DSIZE::OffsetX::U8), + ( + disp_min_y + DSIZE::OffsetY::U8, + disp_min_x + DSIZE::OffsetX::U8, + ), + ( + disp_max_y + DSIZE::OffsetY::U8, + disp_max_x + DSIZE::OffsetX::U8, + ), )?; self.properties.bounded_draw( diff --git a/src/mode/terminal.rs b/src/mode/terminal.rs index 0244faf9..57688493 100644 --- a/src/mode/terminal.rs +++ b/src/mode/terminal.rs @@ -25,8 +25,8 @@ //! } //! ``` -use typenum::{Unsigned, U128, U64, U24, U45, U48}; use display_interface::{DisplayError, WriteOnlyDataCommand}; +use typenum::{Unsigned, U128, U24, U45, U48, U64}; use crate::{ brightness::Brightness, @@ -194,7 +194,6 @@ where { /// Clear the display and reset the cursor to the top left corner pub fn clear(&mut self) -> Result<(), TerminalModeError> { - // The number of characters that can fit on the display at once (w * h / (8 * 8)) let numchars = DSIZE::CharNum::U8; diff --git a/src/properties.rs b/src/properties.rs index 47578c80..2fc9b806 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -1,5 +1,4 @@ //! Container to store and set display properties -use typenum::Unsigned; use crate::mode::displaymode::DisplayModeTrait; use crate::{ brightness::Brightness, @@ -8,6 +7,7 @@ use crate::{ displaysize::DisplaySize, }; use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; +use typenum::Unsigned; /// Display properties struct pub struct DisplayProperties { @@ -22,10 +22,7 @@ where DSIZE: DisplaySize, { /// Create new DisplayProperties instance - pub fn new( - iface: DI, - display_rotation: DisplayRotation, - ) -> DisplayProperties { + pub fn new(iface: DI, display_rotation: DisplayRotation) -> DisplayProperties { DisplayProperties { iface, display_rotation, @@ -42,7 +39,7 @@ impl DisplayProperties { } } -impl DisplayProperties +impl DisplayProperties where DI: WriteOnlyDataCommand, DSIZE: DisplaySize, @@ -188,8 +185,12 @@ where /// ``` pub fn get_dimensions(&self) -> (u8, u8) { match self.display_rotation { - DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => (DSIZE::Width::U8, DSIZE::Height::U8), - DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => (DSIZE::Height::U8, DSIZE::Width::U8), + DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { + (DSIZE::Width::U8, DSIZE::Height::U8) + } + DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { + (DSIZE::Height::U8, DSIZE::Width::U8) + } } } From b53ef588a21815761f3db40b458e697983bbf3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 09:12:19 +0200 Subject: [PATCH 04/21] Make the module public --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4f005855..7f1fae9f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,7 +146,7 @@ pub mod brightness; pub mod builder; mod command; pub mod displayrotation; -mod displaysize; +pub mod displaysize; pub mod mode; pub mod prelude; pub mod properties; From ea46e9f206acce72ab5799eac05391b377762aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 09:27:56 +0200 Subject: [PATCH 05/21] Add defaults Try to at least be backwards compatible when the defaults are used --- src/mode/graphics.rs | 4 ++-- src/mode/terminal.rs | 2 +- src/properties.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index 781b5853..77595134 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -55,7 +55,7 @@ //! //! [embedded_graphics]: https://crates.io/crates/embedded_graphics -use crate::displaysize::DisplaySize; +use crate::displaysize::{DisplaySize, DisplaySize128x64}; use display_interface::{DisplayError, WriteOnlyDataCommand}; use generic_array::GenericArray; use hal::{blocking::delay::DelayMs, digital::v2::OutputPin}; @@ -68,7 +68,7 @@ use crate::{ // TODO: Add to prelude /// Graphics mode handler -pub struct GraphicsMode +pub struct GraphicsMode where DSIZE: DisplaySize, { diff --git a/src/mode/terminal.rs b/src/mode/terminal.rs index 57688493..ae5169c8 100644 --- a/src/mode/terminal.rs +++ b/src/mode/terminal.rs @@ -160,7 +160,7 @@ impl IntoTerminalModeResult for Result { // TODO: Add to prelude /// Terminal mode handler -pub struct TerminalMode +pub struct TerminalMode where DSIZE: TerminalDisplaySize, { diff --git a/src/properties.rs b/src/properties.rs index 2fc9b806..2137f631 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -4,13 +4,13 @@ use crate::{ brightness::Brightness, command::{AddrMode, Command, VcomhLevel}, displayrotation::DisplayRotation, - displaysize::DisplaySize, + displaysize::{DisplaySize, DisplaySize128x64}, }; use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; use typenum::Unsigned; /// Display properties struct -pub struct DisplayProperties { +pub struct DisplayProperties { iface: DI, display_rotation: DisplayRotation, addr_mode: AddrMode, From 3478024c094b32808525edeb5619692a77d8e225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 15:50:55 +0200 Subject: [PATCH 06/21] Implemented suggested changes --- src/displaysize.rs | 58 +++++++++++++++++++------------------------- src/mode/graphics.rs | 24 +++++++++--------- src/mode/terminal.rs | 34 ++++++++++++-------------- src/properties.rs | 9 +++---- 4 files changed, 56 insertions(+), 69 deletions(-) diff --git a/src/displaysize.rs b/src/displaysize.rs index 866b6f47..93a80d95 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -2,81 +2,73 @@ use super::command::Command; use generic_array::ArrayLength; -use typenum::{ - Unsigned, U0, U1024, U128, U16, U192, U28, U32, U360, U384, U40, U48, U512, U64, U72, U96, -}; +use typenum::{U1024, U192, U360, U384, U512}; pub trait DisplaySize { - type Width: Unsigned; - type Height: Unsigned; - type OffsetX: Unsigned; - type OffsetY: Unsigned; + const WIDTH: u8; + const HEIGHT: u8; + const OFFSETX: u8 = 0; + const OFFSETY: u8 = 0; type BufferSize: ArrayLength; - fn ComPinConfig() -> Command; + fn com_pin_config() -> Command; } pub struct DisplaySize128x64; impl DisplaySize for DisplaySize128x64 { - type Width = U128; - type Height = U64; - type OffsetX = U0; - type OffsetY = U0; + const WIDTH: u8 = 128; + const HEIGHT: u8 = 64; type BufferSize = U1024; - fn ComPinConfig() -> Command { + fn com_pin_config() -> Command { Command::ComPinConfig(true, false) } } pub struct DisplaySize128x32; impl DisplaySize for DisplaySize128x32 { - type Width = U128; - type Height = U32; - type OffsetX = U0; - type OffsetY = U0; + const WIDTH: u8 = 128; + const HEIGHT: u8 = 32; type BufferSize = U512; - fn ComPinConfig() -> Command { + fn com_pin_config() -> Command { Command::ComPinConfig(false, false) } } pub struct DisplaySize96x16; impl DisplaySize for DisplaySize96x16 { - type Width = U96; - type Height = U16; - type OffsetX = U0; - type OffsetY = U0; + const WIDTH: u8 = 96; + const HEIGHT: u8 = 16; type BufferSize = U192; - fn ComPinConfig() -> Command { + fn com_pin_config() -> Command { Command::ComPinConfig(false, false) } } pub struct DisplaySize72x40; impl DisplaySize for DisplaySize72x40 { - type Width = U72; - type Height = U40; - type OffsetX = U28; - type OffsetY = U0; + const WIDTH: u8 = 72; + const HEIGHT: u8 = 40; + const OFFSETX: u8 = 28; + const OFFSETY: u8 = 0; type BufferSize = U360; - fn ComPinConfig() -> Command { + fn com_pin_config() -> Command { Command::ComPinConfig(true, false) } } pub struct DisplaySize64x48; impl DisplaySize for DisplaySize64x48 { - type Width = U64; - type Height = U48; - type OffsetX = U32; - type OffsetY = U0; + const WIDTH: u8 = 64; + const HEIGHT: u8 = 48; + const OFFSETX: u8 = 32; + const OFFSETY: u8 = 0; type BufferSize = U384; - fn ComPinConfig() -> Command { + fn com_pin_config() -> Command { Command::ComPinConfig(true, false) } } diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index 77595134..3a8c3a87 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -58,8 +58,6 @@ use crate::displaysize::{DisplaySize, DisplaySize128x64}; use display_interface::{DisplayError, WriteOnlyDataCommand}; use generic_array::GenericArray; -use hal::{blocking::delay::DelayMs, digital::v2::OutputPin}; -use typenum::Unsigned; use crate::{ brightness::Brightness, displayrotation::DisplayRotation, mode::displaymode::DisplayModeTrait, @@ -102,7 +100,7 @@ where } } -impl GraphicsMode +impl GraphicsMode where DSIZE: DisplaySize, DI: WriteOnlyDataCommand, @@ -152,12 +150,12 @@ where DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { self.properties.set_draw_area( ( - disp_min_x + DSIZE::OffsetX::U8, - disp_min_y + DSIZE::OffsetY::U8, + disp_min_x + DSIZE::OFFSETX, + disp_min_y + DSIZE::OFFSETY, ), ( - disp_max_x + DSIZE::OffsetX::U8, - disp_max_y + DSIZE::OffsetY::U8, + disp_max_x + DSIZE::OFFSETX, + disp_max_y + DSIZE::OFFSETY, ), )?; @@ -171,12 +169,12 @@ where DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { self.properties.set_draw_area( ( - disp_min_y + DSIZE::OffsetY::U8, - disp_min_x + DSIZE::OffsetX::U8, + disp_min_y + DSIZE::OFFSETY, + disp_min_x + DSIZE::OFFSETX, ), ( - disp_max_y + DSIZE::OffsetY::U8, - disp_max_x + DSIZE::OffsetX::U8, + disp_max_y + DSIZE::OFFSETY, + disp_max_x + DSIZE::OFFSETX, ), )?; @@ -197,13 +195,13 @@ where let (idx, bit) = match display_rotation { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { - let idx = ((y as usize) / 8 * DSIZE::Width::U8 as usize) + (x as usize); + let idx = ((y as usize) / 8 * DSIZE::WIDTH as usize) + (x as usize); let bit = y % 8; (idx, bit) } DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { - let idx = ((x as usize) / 8 * DSIZE::Width::U8 as usize) + (y as usize); + let idx = ((x as usize) / 8 * DSIZE::WIDTH as usize) + (y as usize); let bit = x % 8; (idx, bit) diff --git a/src/mode/terminal.rs b/src/mode/terminal.rs index ae5169c8..0265f62d 100644 --- a/src/mode/terminal.rs +++ b/src/mode/terminal.rs @@ -26,7 +26,6 @@ //! ``` use display_interface::{DisplayError, WriteOnlyDataCommand}; -use typenum::{Unsigned, U128, U24, U45, U48, U64}; use crate::{ brightness::Brightness, @@ -42,27 +41,28 @@ use crate::{ use core::{cmp::min, fmt}; pub trait TerminalDisplaySize: DisplaySize { - type CharNum: Unsigned; + /// The number of characters that can fit on the display at once (w * h / (8 * 8)) + const CHAR_NUM: u8; } impl TerminalDisplaySize for DisplaySize128x64 { - type CharNum = U128; + const CHAR_NUM: u8 = 128; } impl TerminalDisplaySize for DisplaySize128x32 { - type CharNum = U64; + const CHAR_NUM: u8 = 64; } impl TerminalDisplaySize for DisplaySize96x16 { - type CharNum = U24; + const CHAR_NUM: u8 = 24; } impl TerminalDisplaySize for DisplaySize72x40 { - type CharNum = U45; + const CHAR_NUM: u8 = 45; } impl TerminalDisplaySize for DisplaySize64x48 { - type CharNum = U48; + const CHAR_NUM: u8 = 48; } /// Contains the new row that the cursor has wrapped around to @@ -187,15 +187,13 @@ where } } -impl TerminalMode +impl TerminalMode where - DSIZE: TerminalDisplaySize, DI: WriteOnlyDataCommand, + DSIZE: TerminalDisplaySize, { /// Clear the display and reset the cursor to the top left corner pub fn clear(&mut self) -> Result<(), TerminalModeError> { - // The number of characters that can fit on the display at once (w * h / (8 * 8)) - let numchars = DSIZE::CharNum::U8; // Let the chip handle line wrapping so we can fill the screen with blanks faster self.properties @@ -203,16 +201,16 @@ where .terminal_err()?; self.properties .set_draw_area( - (DSIZE::OffsetX::U8, DSIZE::OffsetY::U8), + (DSIZE::OFFSETX, DSIZE::OFFSETY), ( - DSIZE::Width::U8 + DSIZE::OffsetX::U8, - DSIZE::Height::U8 + DSIZE::OffsetY::U8, + DSIZE::WIDTH + DSIZE::OFFSETX, + DSIZE::HEIGHT + DSIZE::OFFSETY, ), ) .terminal_err()?; // Clear the display - for _ in 0..numchars { + for _ in 0..DSIZE::CHAR_NUM { self.properties.draw(&[0; 8]).terminal_err()?; } @@ -309,11 +307,11 @@ where /// Reset the draw area and move pointer to the top left corner fn reset_pos(&mut self) -> Result<(), TerminalModeError> { self.properties - .set_column(DSIZE::OffsetX::U8) + .set_column(DSIZE::OFFSETX) .terminal_err()?; - self.properties.set_row(DSIZE::OffsetY::U8).terminal_err()?; + self.properties.set_row(DSIZE::OFFSETY).terminal_err()?; // Initialise the counter when we know it's valid - self.cursor = Some(Cursor::new(DSIZE::Width::U8, DSIZE::Height::U8)); + self.cursor = Some(Cursor::new(DSIZE::WIDTH, DSIZE::HEIGHT)); Ok(()) } diff --git a/src/properties.rs b/src/properties.rs index 2137f631..81250ba9 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -7,7 +7,6 @@ use crate::{ displaysize::{DisplaySize, DisplaySize128x64}, }; use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; -use typenum::Unsigned; /// Display properties struct pub struct DisplayProperties { @@ -56,7 +55,7 @@ where Command::DisplayOn(false).send(&mut self.iface)?; Command::DisplayClockDiv(0x8, 0x0).send(&mut self.iface)?; - Command::Multiplex(DSIZE::Height::U8 - 1).send(&mut self.iface)?; + Command::Multiplex(DSIZE::HEIGHT - 1).send(&mut self.iface)?; Command::DisplayOffset(0).send(&mut self.iface)?; Command::StartLine(0).send(&mut self.iface)?; // TODO: Ability to turn charge pump on/off @@ -65,7 +64,7 @@ where self.set_rotation(display_rotation)?; - DSIZE::ComPinConfig().send(&mut self.iface)?; + DSIZE::com_pin_config().send(&mut self.iface)?; self.set_brightness(Brightness::default())?; Command::VcomhDeselect(VcomhLevel::Auto).send(&mut self.iface)?; @@ -186,10 +185,10 @@ where pub fn get_dimensions(&self) -> (u8, u8) { match self.display_rotation { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { - (DSIZE::Width::U8, DSIZE::Height::U8) + (DSIZE::WIDTH, DSIZE::HEIGHT) } DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { - (DSIZE::Height::U8, DSIZE::Width::U8) + (DSIZE::HEIGHT, DSIZE::WIDTH) } } } From 13e680735fadf353f422b807b1cc6303a7f5c5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 16:08:14 +0200 Subject: [PATCH 07/21] Command must be public to allow external implementations of DisplaySize --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 7f1fae9f..637d4534 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -144,7 +144,7 @@ extern crate embedded_hal as hal; pub mod brightness; pub mod builder; -mod command; +pub mod command; pub mod displayrotation; pub mod displaysize; pub mod mode; From ee6452328fef1775e1f0bb8cc443ee6639f29383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 16:16:55 +0200 Subject: [PATCH 08/21] Docs to make CI happy --- src/command.rs | 4 +++- src/displaysize.rs | 27 +++++++++++++++++++++++++++ src/mode/terminal.rs | 2 ++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/command.rs b/src/command.rs index 01a584a3..fd567b3a 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,3 +1,5 @@ +//! Display commands. + // Shamefully taken from https://github.com/EdgewaterDevelopment/rust-ssd1306 use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; @@ -5,7 +7,7 @@ use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; /// SSD1306 Commands /// Commands -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] #[allow(dead_code)] pub enum Command { /// Set contrast. Higher number is higher contrast. Default = 0x7F diff --git a/src/displaysize.rs b/src/displaysize.rs index 93a80d95..3db6a1f1 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -1,19 +1,42 @@ //! Display size +// These are not instantiated, so no need to implement Copy +#![allow(missing_copy_implementations)] + use super::command::Command; use generic_array::ArrayLength; use typenum::{U1024, U192, U360, U384, U512}; +/// Display information +/// +/// This trait describes information related to a particular display. +/// This includes resolution, offset and framebuffer size. pub trait DisplaySize { + + /// Width in pixels const WIDTH: u8; + + /// Height in pixels const HEIGHT: u8; + + /// Horizontal offset in pixels const OFFSETX: u8 = 0; + + /// Vertical offset in pixels const OFFSETY: u8 = 0; + + /// Size of framebuffer. Because the display is monocrome, this is + /// width * height / 8 type BufferSize: ArrayLength; + /// Returns the command to set up com hardware configuration + /// + /// See [`Command::ComPinConfig`](../command/enum.Command.html#variant.ComPinConfig) + /// for more information fn com_pin_config() -> Command; } +/// Size information for the common 128x64 variants pub struct DisplaySize128x64; impl DisplaySize for DisplaySize128x64 { const WIDTH: u8 = 128; @@ -25,6 +48,7 @@ impl DisplaySize for DisplaySize128x64 { } } +/// Size information for the common 128x32 variants pub struct DisplaySize128x32; impl DisplaySize for DisplaySize128x32 { const WIDTH: u8 = 128; @@ -36,6 +60,7 @@ impl DisplaySize for DisplaySize128x32 { } } +/// Size information for the common 96x16 variants pub struct DisplaySize96x16; impl DisplaySize for DisplaySize96x16 { const WIDTH: u8 = 96; @@ -47,6 +72,7 @@ impl DisplaySize for DisplaySize96x16 { } } +/// Size information for the common 72x40 variants pub struct DisplaySize72x40; impl DisplaySize for DisplaySize72x40 { const WIDTH: u8 = 72; @@ -60,6 +86,7 @@ impl DisplaySize for DisplaySize72x40 { } } +/// Size information for the common 64x48 variants pub struct DisplaySize64x48; impl DisplaySize for DisplaySize64x48 { const WIDTH: u8 = 64; diff --git a/src/mode/terminal.rs b/src/mode/terminal.rs index 0265f62d..4120ab9a 100644 --- a/src/mode/terminal.rs +++ b/src/mode/terminal.rs @@ -40,6 +40,8 @@ use crate::{ }; use core::{cmp::min, fmt}; +/// Extends the [`DisplaySize`](../../displaysize/trait.DisplaySize.html) trait +/// to include number of characters that can fit on the display. pub trait TerminalDisplaySize: DisplaySize { /// The number of characters that can fit on the display at once (w * h / (8 * 8)) const CHAR_NUM: u8; From 4e1f1e1fb1d21e18acc6dbae05927678cea87aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 16:24:23 +0200 Subject: [PATCH 09/21] Run cargo fmt --- src/displaysize.rs | 1 - src/mode/graphics.rs | 22 +++++----------------- src/mode/terminal.rs | 5 +---- src/properties.rs | 10 +++------- 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/displaysize.rs b/src/displaysize.rs index 3db6a1f1..2bdec0f7 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -12,7 +12,6 @@ use typenum::{U1024, U192, U360, U384, U512}; /// This trait describes information related to a particular display. /// This includes resolution, offset and framebuffer size. pub trait DisplaySize { - /// Width in pixels const WIDTH: u8; diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index 3a8c3a87..d7338d49 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -66,7 +66,7 @@ use crate::{ // TODO: Add to prelude /// Graphics mode handler -pub struct GraphicsMode +pub struct GraphicsMode where DSIZE: DisplaySize, { @@ -149,14 +149,8 @@ where match self.properties.get_rotation() { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { self.properties.set_draw_area( - ( - disp_min_x + DSIZE::OFFSETX, - disp_min_y + DSIZE::OFFSETY, - ), - ( - disp_max_x + DSIZE::OFFSETX, - disp_max_y + DSIZE::OFFSETY, - ), + (disp_min_x + DSIZE::OFFSETX, disp_min_y + DSIZE::OFFSETY), + (disp_max_x + DSIZE::OFFSETX, disp_max_y + DSIZE::OFFSETY), )?; self.properties.bounded_draw( @@ -168,14 +162,8 @@ where } DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { self.properties.set_draw_area( - ( - disp_min_y + DSIZE::OFFSETY, - disp_min_x + DSIZE::OFFSETX, - ), - ( - disp_max_y + DSIZE::OFFSETY, - disp_max_x + DSIZE::OFFSETX, - ), + (disp_min_y + DSIZE::OFFSETY, disp_min_x + DSIZE::OFFSETX), + (disp_max_y + DSIZE::OFFSETY, disp_max_x + DSIZE::OFFSETX), )?; self.properties.bounded_draw( diff --git a/src/mode/terminal.rs b/src/mode/terminal.rs index 4120ab9a..fb46bc3e 100644 --- a/src/mode/terminal.rs +++ b/src/mode/terminal.rs @@ -196,7 +196,6 @@ where { /// Clear the display and reset the cursor to the top left corner pub fn clear(&mut self) -> Result<(), TerminalModeError> { - // Let the chip handle line wrapping so we can fill the screen with blanks faster self.properties .change_mode(AddrMode::Horizontal) @@ -308,9 +307,7 @@ where /// Reset the draw area and move pointer to the top left corner fn reset_pos(&mut self) -> Result<(), TerminalModeError> { - self.properties - .set_column(DSIZE::OFFSETX) - .terminal_err()?; + self.properties.set_column(DSIZE::OFFSETX).terminal_err()?; self.properties.set_row(DSIZE::OFFSETY).terminal_err()?; // Initialise the counter when we know it's valid self.cursor = Some(Cursor::new(DSIZE::WIDTH, DSIZE::HEIGHT)); diff --git a/src/properties.rs b/src/properties.rs index 81250ba9..29215f4f 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -9,7 +9,7 @@ use crate::{ use display_interface::{DataFormat::U8, DisplayError, WriteOnlyDataCommand}; /// Display properties struct -pub struct DisplayProperties { +pub struct DisplayProperties { iface: DI, display_rotation: DisplayRotation, addr_mode: AddrMode, @@ -184,12 +184,8 @@ where /// ``` pub fn get_dimensions(&self) -> (u8, u8) { match self.display_rotation { - DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { - (DSIZE::WIDTH, DSIZE::HEIGHT) - } - DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => { - (DSIZE::HEIGHT, DSIZE::WIDTH) - } + DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => (DSIZE::WIDTH, DSIZE::HEIGHT), + DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => (DSIZE::HEIGHT, DSIZE::WIDTH), } } From c87abe2db3dce0d09f523c0b1649cdccf233b4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 16:38:20 +0200 Subject: [PATCH 10/21] Fix inference related errors, add display sizes to prelude --- examples/graphics_i2c_128x32.rs | 4 ++-- examples/graphics_i2c_72x40.rs | 4 ++-- src/builder.rs | 16 ++++++++-------- src/prelude.rs | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/graphics_i2c_128x32.rs b/examples/graphics_i2c_128x32.rs index 5b1c7469..147189b1 100644 --- a/examples/graphics_i2c_128x32.rs +++ b/examples/graphics_i2c_128x32.rs @@ -65,8 +65,8 @@ fn main() -> ! { ); let interface = I2CDIBuilder::new().init(i2c); - let mut disp: GraphicsMode<_> = Builder::new() - .size(DisplaySize::Display128x32) + let mut disp: GraphicsMode<_, _> = Builder::new() + .size::() .connect(interface) .into(); disp.init().unwrap(); diff --git a/examples/graphics_i2c_72x40.rs b/examples/graphics_i2c_72x40.rs index 6df84540..4f1287d7 100644 --- a/examples/graphics_i2c_72x40.rs +++ b/examples/graphics_i2c_72x40.rs @@ -65,8 +65,8 @@ fn main() -> ! { ); let interface = I2CDIBuilder::new().init(i2c); - let mut disp: GraphicsMode<_> = Builder::new() - .size(DisplaySize::Display72x40) + let mut disp: GraphicsMode<_, _> = Builder::new() + .size::() .connect(interface) .into(); disp.init().unwrap(); diff --git a/src/builder.rs b/src/builder.rs index f1f945aa..9b03919f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -70,19 +70,13 @@ where _size: core::marker::PhantomData, } -impl Default for Builder -where - DSIZE: DisplaySize, -{ +impl Default for Builder { fn default() -> Self { Self::new() } } -impl Builder -where - DSIZE: DisplaySize, -{ +impl Builder { /// Create new builder with a default size of 128 x 64 pixels and no rotation. pub fn new() -> Self { Self { @@ -90,6 +84,12 @@ where _size: core::marker::PhantomData, } } +} + +impl Builder +where + DSIZE: DisplaySize, +{ /// Set the size of the display. Supported sizes are defined by [DisplaySize]. pub fn size(self) -> Builder { diff --git a/src/prelude.rs b/src/prelude.rs index e5465445..6916afc2 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,6 +7,6 @@ pub use display_interface_spi::{SPIInterface, SPIInterfaceNoCS}; pub use super::{ brightness::Brightness, displayrotation::DisplayRotation, - displaysize::DisplaySize, + displaysize::*, mode::{displaymode::DisplayModeTrait, GraphicsMode, TerminalMode}, }; From a0bdbab5554a67096223ac08b5cfcf0ef484d756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 16:41:00 +0200 Subject: [PATCH 11/21] Fix formatting --- src/builder.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index 9b03919f..e8d21c7a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -90,7 +90,6 @@ impl Builder where DSIZE: DisplaySize, { - /// Set the size of the display. Supported sizes are defined by [DisplaySize]. pub fn size(self) -> Builder { Builder { From 828b6ec009b90140832997a001fbcc587bba776e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 16:46:20 +0200 Subject: [PATCH 12/21] Fix examples in doc comments --- src/builder.rs | 2 +- src/properties.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index e8d21c7a..22711776 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -33,7 +33,7 @@ //! let interface = I2CDIBuilder::new().init(i2c); //! Builder::new() //! .with_rotation(DisplayRotation::Rotate180) -//! .size(DisplaySize::Display128x32) +//! .size::() //! .connect(interface); //! ``` //! diff --git a/src/properties.rs b/src/properties.rs index 29215f4f..e70c6ade 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -169,7 +169,6 @@ where /// # /// let disp = DisplayProperties::new( /// interface, - /// DisplaySize::Display128x64, /// DisplayRotation::Rotate0, /// ); /// assert_eq!(disp.get_dimensions(), (128, 64)); @@ -177,7 +176,6 @@ where /// # let interface = StubInterface; /// let rotated_disp = DisplayProperties::new( /// interface, - /// DisplaySize::Display128x64, /// DisplayRotation::Rotate90, /// ); /// assert_eq!(rotated_disp.get_dimensions(), (64, 128)); From c51b4a119264ba31d2fa89271af928f3e06d3d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 17:08:45 +0200 Subject: [PATCH 13/21] Looks like we need to be explicit with the types --- src/properties.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/properties.rs b/src/properties.rs index e70c6ade..8f4ee3b5 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -167,14 +167,14 @@ where /// # let interface = StubInterface; /// use ssd1306::prelude::*; /// # - /// let disp = DisplayProperties::new( + /// let disp: DisplayProperties<_, DisplaySize128x64> = DisplayProperties::new( /// interface, /// DisplayRotation::Rotate0, /// ); /// assert_eq!(disp.get_dimensions(), (128, 64)); /// /// # let interface = StubInterface; - /// let rotated_disp = DisplayProperties::new( + /// let rotated_disp: DisplayProperties<_, DisplaySize128x64> = DisplayProperties::new( /// interface, /// DisplayRotation::Rotate90, /// ); From 7529a8cdece50abf73d17b3f35f14de35e1e537d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 12 Jun 2020 21:36:13 +0200 Subject: [PATCH 14/21] Modify configuration to send the command instead of just constructing it This will align better with rotation where at least two commands must be transmitted for configuration --- src/displaysize.rs | 25 +++++++++++++------------ src/properties.rs | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/displaysize.rs b/src/displaysize.rs index 2bdec0f7..869a8899 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -3,6 +3,7 @@ // These are not instantiated, so no need to implement Copy #![allow(missing_copy_implementations)] +use display_interface::{DisplayError, WriteOnlyDataCommand}; use super::command::Command; use generic_array::ArrayLength; use typenum::{U1024, U192, U360, U384, U512}; @@ -28,11 +29,11 @@ pub trait DisplaySize { /// width * height / 8 type BufferSize: ArrayLength; - /// Returns the command to set up com hardware configuration + /// Send resolution-dependent configuration to the display /// /// See [`Command::ComPinConfig`](../command/enum.Command.html#variant.ComPinConfig) /// for more information - fn com_pin_config() -> Command; + fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError>; } /// Size information for the common 128x64 variants @@ -42,8 +43,8 @@ impl DisplaySize for DisplaySize128x64 { const HEIGHT: u8 = 64; type BufferSize = U1024; - fn com_pin_config() -> Command { - Command::ComPinConfig(true, false) + fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + Command::ComPinConfig(true, false).send(iface) } } @@ -54,8 +55,8 @@ impl DisplaySize for DisplaySize128x32 { const HEIGHT: u8 = 32; type BufferSize = U512; - fn com_pin_config() -> Command { - Command::ComPinConfig(false, false) + fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + Command::ComPinConfig(false, false).send(iface) } } @@ -66,8 +67,8 @@ impl DisplaySize for DisplaySize96x16 { const HEIGHT: u8 = 16; type BufferSize = U192; - fn com_pin_config() -> Command { - Command::ComPinConfig(false, false) + fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + Command::ComPinConfig(false, false).send(iface) } } @@ -80,8 +81,8 @@ impl DisplaySize for DisplaySize72x40 { const OFFSETY: u8 = 0; type BufferSize = U360; - fn com_pin_config() -> Command { - Command::ComPinConfig(true, false) + fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + Command::ComPinConfig(true, false).send(iface) } } @@ -94,7 +95,7 @@ impl DisplaySize for DisplaySize64x48 { const OFFSETY: u8 = 0; type BufferSize = U384; - fn com_pin_config() -> Command { - Command::ComPinConfig(true, false) + fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + Command::ComPinConfig(true, false).send(iface) } } diff --git a/src/properties.rs b/src/properties.rs index 8f4ee3b5..f0e6f292 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -64,7 +64,7 @@ where self.set_rotation(display_rotation)?; - DSIZE::com_pin_config().send(&mut self.iface)?; + DSIZE::configure(&mut self.iface)?; self.set_brightness(Brightness::default())?; Command::VcomhDeselect(VcomhLevel::Auto).send(&mut self.iface)?; From 748f8cee4cd865be4d22ec96d322f1731da3cba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 16 Jun 2020 13:54:31 +0200 Subject: [PATCH 15/21] Cleanup --- examples/graphics_i2c_128x32.rs | 2 +- examples/graphics_i2c_72x40.rs | 2 +- src/builder.rs | 12 ++++++------ src/displaysize.rs | 16 ++++++++-------- src/properties.rs | 19 ++++++++++++------- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/examples/graphics_i2c_128x32.rs b/examples/graphics_i2c_128x32.rs index 147189b1..1af3a32c 100644 --- a/examples/graphics_i2c_128x32.rs +++ b/examples/graphics_i2c_128x32.rs @@ -66,7 +66,7 @@ fn main() -> ! { let interface = I2CDIBuilder::new().init(i2c); let mut disp: GraphicsMode<_, _> = Builder::new() - .size::() + .size(DisplaySize128x32) .connect(interface) .into(); disp.init().unwrap(); diff --git a/examples/graphics_i2c_72x40.rs b/examples/graphics_i2c_72x40.rs index 4f1287d7..16491c03 100644 --- a/examples/graphics_i2c_72x40.rs +++ b/examples/graphics_i2c_72x40.rs @@ -66,7 +66,7 @@ fn main() -> ! { let interface = I2CDIBuilder::new().init(i2c); let mut disp: GraphicsMode<_, _> = Builder::new() - .size::() + .size(DisplaySize72x40) .connect(interface) .into(); disp.init().unwrap(); diff --git a/src/builder.rs b/src/builder.rs index 22711776..d3899a30 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -33,7 +33,7 @@ //! let interface = I2CDIBuilder::new().init(i2c); //! Builder::new() //! .with_rotation(DisplayRotation::Rotate180) -//! .size::() +//! .size(DisplaySize128x32) //! .connect(interface); //! ``` //! @@ -66,8 +66,8 @@ pub struct Builder where DSIZE: DisplaySize, { + size: DSIZE, rotation: DisplayRotation, - _size: core::marker::PhantomData, } impl Default for Builder { @@ -80,8 +80,8 @@ impl Builder { /// Create new builder with a default size of 128 x 64 pixels and no rotation. pub fn new() -> Self { Self { + size: DisplaySize128x64, rotation: DisplayRotation::Rotate0, - _size: core::marker::PhantomData, } } } @@ -91,10 +91,10 @@ where DSIZE: DisplaySize, { /// Set the size of the display. Supported sizes are defined by [DisplaySize]. - pub fn size(self) -> Builder { + pub fn size(self, size: S) -> Builder { Builder { + size, rotation: self.rotation, - _size: core::marker::PhantomData, } } @@ -112,7 +112,7 @@ where where I: WriteOnlyDataCommand, { - DisplayProperties::new(interface, self.rotation) + DisplayProperties::new(interface, self.size, self.rotation) } } diff --git a/src/displaysize.rs b/src/displaysize.rs index 869a8899..bac2f5a2 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -1,10 +1,10 @@ //! Display size -// These are not instantiated, so no need to implement Copy +// No need to implement Copy #![allow(missing_copy_implementations)] -use display_interface::{DisplayError, WriteOnlyDataCommand}; use super::command::Command; +use display_interface::{DisplayError, WriteOnlyDataCommand}; use generic_array::ArrayLength; use typenum::{U1024, U192, U360, U384, U512}; @@ -33,7 +33,7 @@ pub trait DisplaySize { /// /// See [`Command::ComPinConfig`](../command/enum.Command.html#variant.ComPinConfig) /// for more information - fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError>; + fn configure(&self, iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError>; } /// Size information for the common 128x64 variants @@ -43,7 +43,7 @@ impl DisplaySize for DisplaySize128x64 { const HEIGHT: u8 = 64; type BufferSize = U1024; - fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + fn configure(&self, iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { Command::ComPinConfig(true, false).send(iface) } } @@ -55,7 +55,7 @@ impl DisplaySize for DisplaySize128x32 { const HEIGHT: u8 = 32; type BufferSize = U512; - fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + fn configure(&self, iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { Command::ComPinConfig(false, false).send(iface) } } @@ -67,7 +67,7 @@ impl DisplaySize for DisplaySize96x16 { const HEIGHT: u8 = 16; type BufferSize = U192; - fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + fn configure(&self, iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { Command::ComPinConfig(false, false).send(iface) } } @@ -81,7 +81,7 @@ impl DisplaySize for DisplaySize72x40 { const OFFSETY: u8 = 0; type BufferSize = U360; - fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + fn configure(&self, iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { Command::ComPinConfig(true, false).send(iface) } } @@ -95,7 +95,7 @@ impl DisplaySize for DisplaySize64x48 { const OFFSETY: u8 = 0; type BufferSize = U384; - fn configure(iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { + fn configure(&self, iface: &mut impl WriteOnlyDataCommand) -> Result<(), DisplayError> { Command::ComPinConfig(true, false).send(iface) } } diff --git a/src/properties.rs b/src/properties.rs index f0e6f292..fd0205ec 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -13,7 +13,7 @@ pub struct DisplayProperties { iface: DI, display_rotation: DisplayRotation, addr_mode: AddrMode, - _size: core::marker::PhantomData, + size: DSIZE, } impl DisplayProperties @@ -21,12 +21,16 @@ where DSIZE: DisplaySize, { /// Create new DisplayProperties instance - pub fn new(iface: DI, display_rotation: DisplayRotation) -> DisplayProperties { + pub fn new( + iface: DI, + size: DSIZE, + display_rotation: DisplayRotation, + ) -> DisplayProperties { DisplayProperties { iface, display_rotation, addr_mode: AddrMode::Page, // reset value - _size: core::marker::PhantomData, + size, } } } @@ -62,10 +66,9 @@ where Command::ChargePump(true).send(&mut self.iface)?; Command::AddressMode(mode).send(&mut self.iface)?; + self.size.configure(&mut self.iface)?; self.set_rotation(display_rotation)?; - DSIZE::configure(&mut self.iface)?; - self.set_brightness(Brightness::default())?; Command::VcomhDeselect(VcomhLevel::Auto).send(&mut self.iface)?; Command::AllOn(false).send(&mut self.iface)?; @@ -167,15 +170,17 @@ where /// # let interface = StubInterface; /// use ssd1306::prelude::*; /// # - /// let disp: DisplayProperties<_, DisplaySize128x64> = DisplayProperties::new( + /// let disp = DisplayProperties::new( /// interface, + /// DisplaySize128x64, /// DisplayRotation::Rotate0, /// ); /// assert_eq!(disp.get_dimensions(), (128, 64)); /// /// # let interface = StubInterface; - /// let rotated_disp: DisplayProperties<_, DisplaySize128x64> = DisplayProperties::new( + /// let rotated_disp = DisplayProperties::new( /// interface, + /// DisplaySize128x64, /// DisplayRotation::Rotate90, /// ); /// assert_eq!(rotated_disp.get_dimensions(), (64, 128)); From 7293e42096bc752172e7d572f7a7ec9f351836fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 16 Jun 2020 14:22:11 +0200 Subject: [PATCH 16/21] Remove outdated todo --- src/mode/graphics.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index d7338d49..13afe12f 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -64,7 +64,6 @@ use crate::{ properties::DisplayProperties, }; -// TODO: Add to prelude /// Graphics mode handler pub struct GraphicsMode where From f988370334789ace8a9a55d66f95d28883170566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 16 Jun 2020 14:23:22 +0200 Subject: [PATCH 17/21] No glob reexport --- src/prelude.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prelude.rs b/src/prelude.rs index 6916afc2..8490de7f 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,6 +7,8 @@ pub use display_interface_spi::{SPIInterface, SPIInterfaceNoCS}; pub use super::{ brightness::Brightness, displayrotation::DisplayRotation, - displaysize::*, + displaysize::{ + DisplaySize128x32, DisplaySize128x64, DisplaySize64x48, DisplaySize72x40, DisplaySize96x16, + }, mode::{displaymode::DisplayModeTrait, GraphicsMode, TerminalMode}, }; From 3f0ab04ef8852fd6a1d58d80db88f20f49fa4be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 16 Jun 2020 14:33:15 +0200 Subject: [PATCH 18/21] Add note about second type param, add properties to prelude --- src/builder.rs | 16 +++++++++++++++- src/prelude.rs | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index d3899a30..5e3aadd6 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -31,7 +31,21 @@ //! use ssd1306::{prelude::*, Builder, I2CDIBuilder}; //! //! let interface = I2CDIBuilder::new().init(i2c); -//! Builder::new() +//! let di: DisplayProperties<_> = Builder::new() +//! .with_rotation(DisplayRotation::Rotate180) +//! .connect(interface); +//! ``` +//! +//! When using a display other than the 128 x 64, you need to specify the display size in the +//! second type parameter: +//! +//! ```rust +//! # use ssd1306::test_helpers::{PinStub, I2cStub}; +//! # let i2c = I2cStub; +//! use ssd1306::{prelude::*, Builder, I2CDIBuilder}; +//! +//! let interface = I2CDIBuilder::new().init(i2c); +//! let di: DisplayProperties<_, _> = Builder::new() //! .with_rotation(DisplayRotation::Rotate180) //! .size(DisplaySize128x32) //! .connect(interface); diff --git a/src/prelude.rs b/src/prelude.rs index 8490de7f..54082fee 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -11,4 +11,5 @@ pub use super::{ DisplaySize128x32, DisplaySize128x64, DisplaySize64x48, DisplaySize72x40, DisplaySize96x16, }, mode::{displaymode::DisplayModeTrait, GraphicsMode, TerminalMode}, + properties::DisplayProperties, }; From 272f686ab746f27b4479b182a26900ec0895174c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 16 Jun 2020 14:33:20 +0200 Subject: [PATCH 19/21] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f853273..8350237a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Changed +- **(breaking)** [#125](https://github.com/jamwaffles/ssd1306/pull/125) Redesigned display size handling. - **(breaking)** [#126](https://github.com/jamwaffles/ssd1306/pull/126) Moved `reset` method to `DisplayModeTrait`. If the prelude is not used, add either `use ssd1306::prelude::*` or `ssd1306::mode::displaymode::DisplayModeTrait` to your imports. - **(breaking)** [#119](https://github.com/jamwaffles/ssd1306/pull/119) Remove `DisplayMode` and `RawMode` - [#120](https://github.com/jamwaffles/ssd1306/pull/120) Update to v0.4 [`display-interface`](https://crates.io/crates/display-interface) From de23b05e1a5ba34311c791325447848f3c802365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 16 Jun 2020 14:47:45 +0200 Subject: [PATCH 20/21] Fix resetting the dirty drawing area coordinates --- src/mode/graphics.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mode/graphics.rs b/src/mode/graphics.rs index 13afe12f..1e9f7ae9 100644 --- a/src/mode/graphics.rs +++ b/src/mode/graphics.rs @@ -64,6 +64,7 @@ use crate::{ properties::DisplayProperties, }; +// TODO: Add to prelude /// Graphics mode handler pub struct GraphicsMode where @@ -139,9 +140,9 @@ where } }; - self.min_x = width - 1; + self.min_x = 255; self.max_x = 0; - self.min_y = width - 1; + self.min_y = 255; self.max_y = 0; // Tell the display to update only the part that has changed From 48c490ff3607a893b2681716536a69cd9f1979f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 23 Jun 2020 11:39:25 +0200 Subject: [PATCH 21/21] Apply suggestions from code review Co-authored-by: James Waples --- Cargo.toml | 1 - src/builder.rs | 5 +++-- src/displaysize.rs | 14 +++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4235315a..cfbb8a96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ embedded-hal = "0.2.3" display-interface = "0.4" display-interface-i2c = "0.4" display-interface-spi = "0.4" -typenum = "1.12.0" generic-array = "0.14.2" [dependencies.embedded-graphics] diff --git a/src/builder.rs b/src/builder.rs index 5e3aadd6..79794c26 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -36,8 +36,9 @@ //! .connect(interface); //! ``` //! -//! When using a display other than the 128 x 64, you need to specify the display size in the -//! second type parameter: +//! The builder defaults to a display size of 128 x 64px. To use a display with a different size, +//! call the [`size`](#method.size) method. Supported sizes can be found in the +//! [`displaysize`](../displaysize/index.html) module or in the [prelude](../prelude/index.html). //! //! ```rust //! # use ssd1306::test_helpers::{PinStub, I2cStub}; diff --git a/src/displaysize.rs b/src/displaysize.rs index bac2f5a2..fd386017 100644 --- a/src/displaysize.rs +++ b/src/displaysize.rs @@ -1,12 +1,11 @@ //! Display size -// No need to implement Copy -#![allow(missing_copy_implementations)] - use super::command::Command; use display_interface::{DisplayError, WriteOnlyDataCommand}; -use generic_array::ArrayLength; -use typenum::{U1024, U192, U360, U384, U512}; +use generic_array::{ + typenum::{U1024, U192, U360, U384, U512}, + ArrayLength, +}; /// Display information /// @@ -37,6 +36,7 @@ pub trait DisplaySize { } /// Size information for the common 128x64 variants +#[derive(Debug, Copy, Clone)] pub struct DisplaySize128x64; impl DisplaySize for DisplaySize128x64 { const WIDTH: u8 = 128; @@ -49,6 +49,7 @@ impl DisplaySize for DisplaySize128x64 { } /// Size information for the common 128x32 variants +#[derive(Debug, Copy, Clone)] pub struct DisplaySize128x32; impl DisplaySize for DisplaySize128x32 { const WIDTH: u8 = 128; @@ -61,6 +62,7 @@ impl DisplaySize for DisplaySize128x32 { } /// Size information for the common 96x16 variants +#[derive(Debug, Copy, Clone)] pub struct DisplaySize96x16; impl DisplaySize for DisplaySize96x16 { const WIDTH: u8 = 96; @@ -73,6 +75,7 @@ impl DisplaySize for DisplaySize96x16 { } /// Size information for the common 72x40 variants +#[derive(Debug, Copy, Clone)] pub struct DisplaySize72x40; impl DisplaySize for DisplaySize72x40 { const WIDTH: u8 = 72; @@ -87,6 +90,7 @@ impl DisplaySize for DisplaySize72x40 { } /// Size information for the common 64x48 variants +#[derive(Debug, Copy, Clone)] pub struct DisplaySize64x48; impl DisplaySize for DisplaySize64x48 { const WIDTH: u8 = 64;