mirror of
https://github.com/yuri91/ili9341-rs.git
synced 2024-11-23 23:21:00 +00:00
Merge pull request #29 from ivmarkov/master
Support for boards that need a non-standard initialization command
This commit is contained in:
commit
c3d0d08a3c
1 changed files with 48 additions and 33 deletions
81
src/lib.rs
81
src/lib.rs
|
@ -40,7 +40,19 @@ impl DisplaySize for DisplaySize320x480 {
|
||||||
const HEIGHT: usize = 480;
|
const HEIGHT: usize = 480;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The default orientation is Portrait
|
/// For quite a few boards (ESP32-S2-Kaluga-1, M5Stack, M5Core2 and others),
|
||||||
|
/// the ILI9341 initialization command arguments are slightly different
|
||||||
|
///
|
||||||
|
/// This trait provides the flexibility for users to define their own
|
||||||
|
/// initialization command arguments suitable for the particular board they are using
|
||||||
|
pub trait Mode {
|
||||||
|
fn mode(&self) -> u8;
|
||||||
|
|
||||||
|
fn is_landscape(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The default implementation of the Mode trait from above
|
||||||
|
/// Should work for most (but not all) boards
|
||||||
pub enum Orientation {
|
pub enum Orientation {
|
||||||
Portrait,
|
Portrait,
|
||||||
PortraitFlipped,
|
PortraitFlipped,
|
||||||
|
@ -48,6 +60,24 @@ pub enum Orientation {
|
||||||
LandscapeFlipped,
|
LandscapeFlipped,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mode for Orientation {
|
||||||
|
fn mode(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
Self::Portrait => 0x40 | 0x08,
|
||||||
|
Self::Landscape => 0x20 | 0x08,
|
||||||
|
Self::PortraitFlipped => 0x80 | 0x08,
|
||||||
|
Self::LandscapeFlipped => 0x40 | 0x80 | 0x20 | 0x08,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_landscape(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Landscape | Self::LandscapeFlipped => true,
|
||||||
|
Self::Portrait | Self::PortraitFlipped => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// There are two method for drawing to the screen:
|
/// There are two method for drawing to the screen:
|
||||||
/// [Ili9341::draw_raw_iter] and [Ili9341::draw_raw_slice]
|
/// [Ili9341::draw_raw_iter] and [Ili9341::draw_raw_slice]
|
||||||
///
|
///
|
||||||
|
@ -68,7 +98,7 @@ pub struct Ili9341<IFACE, RESET> {
|
||||||
reset: RESET,
|
reset: RESET,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
mode: Orientation,
|
landscape: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<IFACE, RESET> Ili9341<IFACE, RESET>
|
impl<IFACE, RESET> Ili9341<IFACE, RESET>
|
||||||
|
@ -76,23 +106,24 @@ where
|
||||||
IFACE: WriteOnlyDataCommand,
|
IFACE: WriteOnlyDataCommand,
|
||||||
RESET: OutputPin,
|
RESET: OutputPin,
|
||||||
{
|
{
|
||||||
pub fn new<DELAY, SIZE>(
|
pub fn new<DELAY, SIZE, MODE>(
|
||||||
interface: IFACE,
|
interface: IFACE,
|
||||||
reset: RESET,
|
reset: RESET,
|
||||||
delay: &mut DELAY,
|
delay: &mut DELAY,
|
||||||
mode: Orientation,
|
mode: MODE,
|
||||||
_display_size: SIZE,
|
_display_size: SIZE,
|
||||||
) -> Result<Self>
|
) -> Result<Self>
|
||||||
where
|
where
|
||||||
DELAY: DelayMs<u16>,
|
DELAY: DelayMs<u16>,
|
||||||
SIZE: DisplaySize,
|
SIZE: DisplaySize,
|
||||||
|
MODE: Mode,
|
||||||
{
|
{
|
||||||
let mut ili9341 = Ili9341 {
|
let mut ili9341 = Ili9341 {
|
||||||
interface,
|
interface,
|
||||||
reset,
|
reset,
|
||||||
width: SIZE::WIDTH,
|
width: SIZE::WIDTH,
|
||||||
height: SIZE::HEIGHT,
|
height: SIZE::HEIGHT,
|
||||||
mode: Orientation::Portrait,
|
landscape: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do hardware reset by holding reset low for at least 10us
|
// Do hardware reset by holding reset low for at least 10us
|
||||||
|
@ -172,9 +203,10 @@ where
|
||||||
fixed_top_lines: u16,
|
fixed_top_lines: u16,
|
||||||
fixed_bottom_lines: u16,
|
fixed_bottom_lines: u16,
|
||||||
) -> Result<Scroller> {
|
) -> Result<Scroller> {
|
||||||
let height = match self.mode {
|
let height = if self.landscape {
|
||||||
Orientation::Landscape | Orientation::LandscapeFlipped => self.width,
|
self.width
|
||||||
Orientation::Portrait | Orientation::PortraitFlipped => self.height,
|
} else {
|
||||||
|
self.height
|
||||||
} as u16;
|
} as u16;
|
||||||
let scroll_lines = height as u16 - fixed_top_lines - fixed_bottom_lines;
|
let scroll_lines = height as u16 - fixed_top_lines - fixed_bottom_lines;
|
||||||
|
|
||||||
|
@ -244,33 +276,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the orientation of the screen
|
/// Change the orientation of the screen
|
||||||
pub fn set_orientation(&mut self, mode: Orientation) -> Result {
|
pub fn set_orientation<MODE>(&mut self, mode: MODE) -> Result
|
||||||
let was_landscape = match self.mode {
|
where
|
||||||
Orientation::Landscape | Orientation::LandscapeFlipped => true,
|
MODE: Mode,
|
||||||
Orientation::Portrait | Orientation::PortraitFlipped => false,
|
{
|
||||||
};
|
self.command(Command::MemoryAccessControl, &[mode.mode()])?;
|
||||||
let is_landscape = match mode {
|
|
||||||
Orientation::Portrait => {
|
if self.landscape ^ mode.is_landscape() {
|
||||||
self.command(Command::MemoryAccessControl, &[0x40 | 0x08])?;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
Orientation::Landscape => {
|
|
||||||
self.command(Command::MemoryAccessControl, &[0x20 | 0x08])?;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
Orientation::PortraitFlipped => {
|
|
||||||
self.command(Command::MemoryAccessControl, &[0x80 | 0x08])?;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
Orientation::LandscapeFlipped => {
|
|
||||||
self.command(Command::MemoryAccessControl, &[0x40 | 0x80 | 0x20 | 0x08])?;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if was_landscape ^ is_landscape {
|
|
||||||
core::mem::swap(&mut self.height, &mut self.width);
|
core::mem::swap(&mut self.height, &mut self.width);
|
||||||
}
|
}
|
||||||
self.mode = mode;
|
self.landscape = mode.is_landscape();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue