embedded_display_controller/lib.rs
1//! Traits for display controllers
2//!
3//! This crate contains traits that represent display controllers with a
4//! memory-backed framebuffer. These controllers are typically integrated into a
5//! System on Chip (SoC) and are used to drive larger / higher performance
6//! displays.
7//!
8//! Note that this crate is *not* aimed at smaller displays that are updated by
9//! sending commands over a low-speed databus (SPI, I2C, ..). These typically
10//! have individual driver crates (some examples are listed
11//! [here](https://github.com/embedded-graphics/embedded-graphics#display-drivers)).
12//! Also note that this crate does not cover functionality available through the
13//! panel's own line drivers or management controller. This crate only covers
14//! the controller in the SoC.
15//!
16//! This crate allows libraries for operating on display layers to be written
17//! independently of the exact controller architecture.
18//!
19//! ## License
20//!
21//! Licensed under either of
22//!
23//! * Apache License, Version 2.0
24//! ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
25//! * MIT license
26//! ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
27//!
28//! at your option.
29//!
30//! ## Contribution
31//!
32//! Unless you explicitly state otherwise, any contribution intentionally
33//! submitted for inclusion in the work by you, as defined in the Apache-2.0
34//! license, shall be dual licensed as above, without any additional terms or
35//! conditions.
36#![no_std]
37
38pub mod dsi;
39
40/// A word type for the display memory buffer
41pub trait PixelWord: Copy {}
42impl PixelWord for u8 {}
43impl PixelWord for u16 {}
44impl PixelWord for u32 {}
45
46/// Pixel memory layouts
47///
48/// * `L8`: 8-bit luminance or CLUT
49/// * `AL44`: 4-bit alpha + 4-bit luminance
50/// * `AL88`: 8-bit alpha + 8-bit luminance
51#[derive(Clone, Copy, Debug, PartialEq)]
52pub enum PixelFormat {
53 ARGB8888 = 0,
54 RGB888,
55 RGB565,
56 ARGB1555,
57 ARGB4444,
58 L8,
59 AL44,
60 AL88,
61}
62
63/// Display configuration parameters
64#[derive(Clone, Copy, Debug, PartialEq)]
65pub struct DisplayConfiguration {
66 pub active_width: u16,
67 pub active_height: u16,
68
69 pub h_back_porch: u16,
70 pub h_front_porch: u16,
71 pub v_back_porch: u16,
72 pub v_front_porch: u16,
73
74 pub h_sync: u16,
75 pub v_sync: u16,
76
77 /// horizontal synchronization: `false`: active low, `true`: active high
78 pub h_sync_pol: bool,
79 /// vertical synchronization: `false`: active low, `true`: active high
80 pub v_sync_pol: bool,
81 /// data enable: `false`: active low, `true`: active high
82 pub not_data_enable_pol: bool,
83 /// pixel_clock: `false`: active low, `true`: active high
84 pub pixel_clock_pol: bool,
85}
86
87/// A microcontroller peripheral that drives a LCD-TFT display
88pub trait DisplayController {
89 /// Initialize the controller with a given configuration
90 fn init(&mut self, config: DisplayConfiguration);
91
92 /// Returns the clock frequency (Hz) of the controller
93 fn clock(&self) -> u32;
94}
95
96/// A layer of a microcontroller peripheral that drives a LCD-TFT display.
97///
98/// May be implemented alongside `DisplayController` if the LCD-TFT display
99/// peripheral only supports one layer.
100pub trait DisplayControllerLayer {
101 /// Enable this display layer.
102 ///
103 /// # Safety
104 ///
105 /// [To be completed by implementation]
106 unsafe fn enable<T: PixelWord>(
107 &mut self,
108 start_ptr: *const T,
109 pixel_format: PixelFormat,
110 );
111
112 /// Swap the framebuffer to a new one.
113 ///
114 /// # Safety
115 ///
116 /// `start_ptr` must point to a location that can be accessed by the LTDC
117 /// peripheral, with sufficient length for the framebuffer.
118 unsafe fn swap_framebuffer<T: PixelWord>(&mut self, start_ptr: *const T);
119
120 /// Indicates that a framebuffer swap is pending. In this situation, memory
121 /// we previously supplied to
122 /// [`swap_framebuffer`](#method.swap_framebuffer), before the most recent
123 /// call, is still owned by the display.
124 fn is_swap_pending(&self) -> bool;
125
126 /// Resizes the framebuffer pitch. This does not change the output window
127 /// size. The shadow registers are reloaded immediately.
128 ///
129 /// The framebuffer pitch is the increment from the start of one line of
130 /// pixels to the start of the next line.
131 ///
132 /// # Safety
133 ///
134 /// The caller must ensure that enough memory is allocated for the resulting
135 /// framebuffer size
136 unsafe fn resize_buffer_pitch(&mut self, width: u32);
137}