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}