mirror of
https://github.com/yuri91/ili9341-rs.git
synced 2024-11-21 22:30:59 +00:00
Merge pull request #21 from almusil/do_not_hardcode_size
Do not hardcode display size
This commit is contained in:
commit
509060bb5d
1 changed files with 65 additions and 26 deletions
91
src/lib.rs
91
src/lib.rs
|
@ -34,8 +34,29 @@ pub trait Interface {
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WIDTH: usize = 240;
|
/// Trait that defines display size information
|
||||||
const HEIGHT: usize = 320;
|
pub trait DisplaySize {
|
||||||
|
/// Width in pixels
|
||||||
|
const WIDTH: usize;
|
||||||
|
/// Height in pixels
|
||||||
|
const HEIGHT: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic display size of 240x320 pixels
|
||||||
|
pub struct DisplaySize240x320;
|
||||||
|
|
||||||
|
impl DisplaySize for DisplaySize240x320 {
|
||||||
|
const WIDTH: usize = 240;
|
||||||
|
const HEIGHT: usize = 320;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic display size of 320x480 pixels
|
||||||
|
pub struct DisplaySize320x480;
|
||||||
|
|
||||||
|
impl DisplaySize for DisplaySize320x480 {
|
||||||
|
const WIDTH: usize = 320;
|
||||||
|
const HEIGHT: usize = 480;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error<PinE> {
|
pub enum Error<PinE> {
|
||||||
|
@ -72,6 +93,7 @@ pub struct Ili9341<IFACE, RESET> {
|
||||||
reset: RESET,
|
reset: RESET,
|
||||||
width: usize,
|
width: usize,
|
||||||
height: usize,
|
height: usize,
|
||||||
|
mode: Orientation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<PinE, IFACE, RESET> Ili9341<IFACE, RESET>
|
impl<PinE, IFACE, RESET> Ili9341<IFACE, RESET>
|
||||||
|
@ -79,16 +101,23 @@ where
|
||||||
IFACE: WriteOnlyDataCommand,
|
IFACE: WriteOnlyDataCommand,
|
||||||
RESET: OutputPin<Error = PinE>,
|
RESET: OutputPin<Error = PinE>,
|
||||||
{
|
{
|
||||||
pub fn new<DELAY: DelayMs<u16>>(
|
pub fn new<DELAY, SIZE>(
|
||||||
interface: IFACE,
|
interface: IFACE,
|
||||||
reset: RESET,
|
reset: RESET,
|
||||||
delay: &mut DELAY,
|
delay: &mut DELAY,
|
||||||
) -> Result<Self, Error<PinE>> {
|
mode: Orientation,
|
||||||
|
_display_size: SIZE,
|
||||||
|
) -> Result<Self, Error<PinE>>
|
||||||
|
where
|
||||||
|
DELAY: DelayMs<u16>,
|
||||||
|
SIZE: DisplaySize,
|
||||||
|
{
|
||||||
let mut ili9341 = Ili9341 {
|
let mut ili9341 = Ili9341 {
|
||||||
interface,
|
interface,
|
||||||
reset,
|
reset,
|
||||||
width: WIDTH,
|
width: SIZE::WIDTH,
|
||||||
height: HEIGHT,
|
height: SIZE::HEIGHT,
|
||||||
|
mode: Orientation::Portrait,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do hardware reset by holding reset low for at least 10us
|
// Do hardware reset by holding reset low for at least 10us
|
||||||
|
@ -108,7 +137,7 @@ where
|
||||||
// and 120ms before sending Sleep Out
|
// and 120ms before sending Sleep Out
|
||||||
delay.delay_ms(120);
|
delay.delay_ms(120);
|
||||||
|
|
||||||
ili9341.set_orientation(Orientation::Portrait)?;
|
ili9341.set_orientation(mode)?;
|
||||||
|
|
||||||
// Set pixel format to 16 bits per pixel
|
// Set pixel format to 16 bits per pixel
|
||||||
ili9341.command(Command::PixelFormatSet, &[0x55])?;
|
ili9341.command(Command::PixelFormatSet, &[0x55])?;
|
||||||
|
@ -167,7 +196,11 @@ where
|
||||||
fixed_top_lines: u16,
|
fixed_top_lines: u16,
|
||||||
fixed_bottom_lines: u16,
|
fixed_bottom_lines: u16,
|
||||||
) -> Result<Scroller, Error<PinE>> {
|
) -> Result<Scroller, Error<PinE>> {
|
||||||
let scroll_lines = HEIGHT as u16 - fixed_top_lines - fixed_bottom_lines;
|
let height = match self.mode {
|
||||||
|
Orientation::Landscape | Orientation::LandscapeFlipped => self.width,
|
||||||
|
Orientation::Portrait | Orientation::PortraitFlipped => self.height,
|
||||||
|
} as u16;
|
||||||
|
let scroll_lines = height as u16 - fixed_top_lines - fixed_bottom_lines;
|
||||||
|
|
||||||
self.command(
|
self.command(
|
||||||
Command::VerticalScrollDefine,
|
Command::VerticalScrollDefine,
|
||||||
|
@ -181,7 +214,7 @@ where
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Scroller::new(fixed_top_lines, fixed_bottom_lines))
|
Ok(Scroller::new(fixed_top_lines, fixed_bottom_lines, height))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_vertically(
|
pub fn scroll_vertically(
|
||||||
|
@ -189,11 +222,10 @@ where
|
||||||
scroller: &mut Scroller,
|
scroller: &mut Scroller,
|
||||||
num_lines: u16,
|
num_lines: u16,
|
||||||
) -> Result<(), Error<PinE>> {
|
) -> Result<(), Error<PinE>> {
|
||||||
let height = HEIGHT as u16;
|
|
||||||
scroller.top_offset += num_lines;
|
scroller.top_offset += num_lines;
|
||||||
if scroller.top_offset > (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
|
||||||
+ (scroller.top_offset - height + scroller.fixed_bottom_lines)
|
+ (scroller.top_offset - scroller.height + scroller.fixed_bottom_lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.command(
|
self.command(
|
||||||
|
@ -249,28 +281,33 @@ where
|
||||||
|
|
||||||
/// 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<(), Error<PinE>> {
|
||||||
match mode {
|
let was_landscape = match self.mode {
|
||||||
|
Orientation::Landscape | Orientation::LandscapeFlipped => true,
|
||||||
|
Orientation::Portrait | Orientation::PortraitFlipped => false,
|
||||||
|
};
|
||||||
|
let is_landscape = match mode {
|
||||||
Orientation::Portrait => {
|
Orientation::Portrait => {
|
||||||
self.width = WIDTH;
|
self.command(Command::MemoryAccessControl, &[0x40 | 0x08])?;
|
||||||
self.height = HEIGHT;
|
false
|
||||||
self.command(Command::MemoryAccessControl, &[0x40 | 0x08])
|
|
||||||
}
|
}
|
||||||
Orientation::Landscape => {
|
Orientation::Landscape => {
|
||||||
self.width = HEIGHT;
|
self.command(Command::MemoryAccessControl, &[0x20 | 0x08])?;
|
||||||
self.height = WIDTH;
|
true
|
||||||
self.command(Command::MemoryAccessControl, &[0x20 | 0x08])
|
|
||||||
}
|
}
|
||||||
Orientation::PortraitFlipped => {
|
Orientation::PortraitFlipped => {
|
||||||
self.width = WIDTH;
|
self.command(Command::MemoryAccessControl, &[0x80 | 0x08])?;
|
||||||
self.height = HEIGHT;
|
false
|
||||||
self.command(Command::MemoryAccessControl, &[0x80 | 0x08])
|
|
||||||
}
|
}
|
||||||
Orientation::LandscapeFlipped => {
|
Orientation::LandscapeFlipped => {
|
||||||
self.width = HEIGHT;
|
self.command(Command::MemoryAccessControl, &[0x40 | 0x80 | 0x20 | 0x08])?;
|
||||||
self.height = WIDTH;
|
true
|
||||||
self.command(Command::MemoryAccessControl, &[0x40 | 0x80 | 0x20 | 0x08])
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if was_landscape ^ is_landscape {
|
||||||
|
core::mem::swap(&mut self.height, &mut self.width);
|
||||||
}
|
}
|
||||||
|
self.mode = mode;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
|
@ -290,14 +327,16 @@ pub struct Scroller {
|
||||||
top_offset: u16,
|
top_offset: u16,
|
||||||
fixed_bottom_lines: u16,
|
fixed_bottom_lines: u16,
|
||||||
fixed_top_lines: u16,
|
fixed_top_lines: u16,
|
||||||
|
height: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scroller {
|
impl Scroller {
|
||||||
fn new(fixed_top_lines: u16, fixed_bottom_lines: u16) -> Scroller {
|
fn new(fixed_top_lines: u16, fixed_bottom_lines: u16, height: u16) -> Scroller {
|
||||||
Scroller {
|
Scroller {
|
||||||
top_offset: fixed_top_lines,
|
top_offset: fixed_top_lines,
|
||||||
fixed_top_lines,
|
fixed_top_lines,
|
||||||
fixed_bottom_lines,
|
fixed_bottom_lines,
|
||||||
|
height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue