### Implementing a custom Model Source: https://context7.com/almindor/mipidsi/llms.txt Guides users on how to extend `mipidsi` for new display controllers by implementing the `Model` trait. This involves defining the `ColorFormat`, `FRAMEBUFFER_SIZE`, and the `init` method, which initializes the controller and returns a `SetAddressMode` value. ```APIDOC ## Implementing a custom Model — Extend mipidsi for new controllers Implement `Model` for a new controller struct. Define `ColorFormat` (an `RgbColor` type), `FRAMEBUFFER_SIZE`, and the `init` method which initializes the controller and returns a `SetAddressMode` (MADCTL) value. ```rust use mipidsi::models::{Model, ModelInitError}; use mipidsi::dcs::{SetAddressMode, SetPixelFormat, PixelFormat, BitsPerPixel, InterfaceExt, ExitSleepMode}; use mipidsi::options::ModelOptions; use mipidsi::interface::Interface; use embedded_graphics::pixelcolor::Rgb565; use embedded_hal::delay::DelayNs; pub struct MyController; impl Model for MyController { type ColorFormat = Rgb565; // Physical framebuffer size of the controller (width, height) const FRAMEBUFFER_SIZE: (u16, u16) = (240, 320); fn init( &mut self, di: &mut DI, delay: &mut DELAY, options: &ModelOptions, ) -> Result> where DELAY: DelayNs, DI: Interface, { // Exit sleep mode di.write_command(ExitSleepMode)?; delay.delay_us(120_000); // Set pixel format to 16-bit RGB565 di.write_command(SetPixelFormat::new( PixelFormat::with_all(BitsPerPixel::Sixteen), ))?; // Build and return MADCTL from current options (color order, orientation, refresh order) let madctl = SetAddressMode::from(options); di.write_command(madctl)?; Ok(madctl) } } // Usage: // let mut display = Builder::new(MyController, di).init(&mut delay).unwrap(); ``` ``` -------------------------------- ### Implement Custom Display Model Source: https://context7.com/almindor/mipidsi/llms.txt Implement the `Model` trait for a new controller struct. Define `ColorFormat`, `FRAMEBUFFER_SIZE`, and the `init` method which initializes the controller and returns a `SetAddressMode` value. This example shows exiting sleep mode, setting pixel format, and building MADCTL from options. ```rust use mipidsi::models::{Model, ModelInitError}; use mipidsi::dcs::{SetAddressMode, SetPixelFormat, PixelFormat, BitsPerPixel, InterfaceExt, ExitSleepMode}; use mipidsi::options::ModelOptions; use mipidsi::interface::Interface; use embedded_graphics::pixelcolor::Rgb565; use embedded_hal::delay::DelayNs; pub struct MyController; impl Model for MyController { type ColorFormat = Rgb565; // Physical framebuffer size of the controller (width, height) const FRAMEBUFFER_SIZE: (u16, u16) = (240, 320); fn init( &mut self, di: &mut DI, delay: &mut DELAY, options: &ModelOptions, ) -> Result> where DELAY: DelayNs, DI: Interface, { // Exit sleep mode di.write_command(ExitSleepMode)?; delay.delay_us(120_000); // Set pixel format to 16-bit RGB565 di.write_command(SetPixelFormat::new( PixelFormat::with_all(BitsPerPixel::Sixteen), ))?; // Build and return MADCTL from current options (color order, orientation, refresh order) let madctl = SetAddressMode::from(options); di.write_command(madctl)?; Ok(madctl) } } // Usage: // let mut display = Builder::new(MyController, di).init(&mut delay).unwrap(); ``` -------------------------------- ### Rename Builder::with_* methods to remove 'with_' prefix Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md Configuration methods on `Builder` have been renamed to remove the `with_` prefix to comply with Rust API guidelines. For example, `with_invert_colors` is now `invert_colors`. ```rust use mipidsi::Builder; let display = Builder::new(ili9341_rgb565, di) .with_invert_colors(ColorInversion::Normal) .with_orientation(Orienation::default()) .init(&mut delay, Some(rst))?; ``` ```rust use mipidsi::{Builder, models::ILI9341Rgb565}; let display = Builder::new(ILI9341Rgb565, di) .invert_colors(ColorInversion::Normal) .orientation(Orienation::default()) .reset_pin(rst) .init(&mut delay)?; ``` -------------------------------- ### Initialize ILI9486 Display with SpiInterface Source: https://github.com/almindor/mipidsi/blob/master/README.md Demonstrates creating an SpiInterface and initializing an ILI9486 display driver. Requires a delay provider and clears the display to black. Ensure the correct color mode (e.g., Rgb666) is specified. ```rust let mut buffer = [0u8; 512]; let di = SpiInterface::new(spi, dc, &mut buffer); let mut display = Builder::new(ILI9486Rgb666, di) .reset_pin(rst) .init(&mut delay)?; display.clear(Rgb666::BLACK)?; ``` -------------------------------- ### Migrate Display Initialization (v0.4 to v0.5) Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md In v0.5, use the Builder pattern to construct the Display and set options before initialization. The reset pin is now optional during init. ```rust let display = Display::st7789(di, rst, DisplayOptions::default()); display.init(&mut delay); ``` ```rust let display = Builder::st7789(di) // known model or with_model(model) .with_display_size(240, 240) // set any options on the builder before init .init(&mut delay, Some(rst)); // optional reset pin ``` -------------------------------- ### Build, Strip, Copy, and Run on Raspberry Pi Zero W (macOS) Source: https://github.com/almindor/mipidsi/blob/master/examples/spi-st7789-rpi-zero-w/README.md Commands to cross-compile a Rust project for a Raspberry Pi Zero W using musl-cross, optimize the binary size, and deploy it to the device via SSH. ```bash # build for rpi zero w cargo build --release --target=arm-unknown-linux-musleabihf # look at the size of the bin file ls -lh target/arm-unknown-linux-musleabihf/release/spi-st7789-rpi-zero-w # strip it arm-linux-musleabihf-strip target/arm-unknown-linux-musleabihf/release/spi-st7789-rpi-zero-w # look at it now ;) ls -lh target/arm-unknown-linux-musleabihf/release/spi-st7789-rpi-zero-w # copy over ssh scp target/arm-unknown-linux-musleabihf/release/spi-st7789-rpi-zero-w pi@raspberrypi.local:~/ # ssh into the rpi to run it ssh pi@raspberrypi.local # run it ./spi-st7789-rpi-zero-w ``` -------------------------------- ### Migrate Display Initialization (v0.3 to v0.4) Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md In v0.4, the `DisplayOptions` argument is passed directly to the constructor instead of the `init` method. ```rust let display = Display::st7789(di, rst); display.init(&mut delay, DisplayOptions::default()); ``` ```rust let display = Display::st7789(di, rst, DisplayOptions::default()); display.init(&mut delay); ``` -------------------------------- ### Builder::new — Construct and Initialize Display Source: https://context7.com/almindor/mipidsi/llms.txt Use Builder::new to create a display driver instance for a specific model and interface. Configure options like color order, inversion, size, and orientation before initializing with `.init()`. Requires an embedded-hal SpiDevice or OutputBus, D/C pin, and a delay implementation. ```rust use mipidsi::interface::SpiInterface; use mipidsi::{Builder, models::ILI9486Rgb666}; use mipidsi::options::{ColorOrder, ColorInversion, Orientation, Rotation}; use embedded_graphics::pixelcolor::Rgb666; // Allocate the SPI transmit buffer (larger = faster, at cost of RAM) let mut buffer = [0_u8; 512]; // Create the SPI interface from an embedded-hal SpiDevice, a D/C pin, and the buffer let di = SpiInterface::new(spi, dc, &mut buffer); // Build and initialize the display driver // .reset_pin(rst) – optional hardware reset pin (must start HIGH) // .color_order(...) – RGB or BGR subpixel order // .invert_colors(...) – Normal or Inverted color output // .display_size(w, h) – override framebuffer active area (pixels) // .display_offset(x,y) – shift active area within the controller framebuffer // .orientation(...) – initial rotation / mirror let mut display = Builder::new(ILI9486Rgb666, di) .reset_pin(rst) .color_order(ColorOrder::Bgr) .invert_colors(ColorInversion::Normal) .display_size(480, 320) .display_offset(0, 0) .orientation(Orientation::new().rotate(Rotation::Deg0)) .init(&mut delay) .unwrap(); // display is now awake and ready; no need to call wake() display.clear(Rgb666::BLACK).unwrap(); ``` -------------------------------- ### SpiInterface::new Source: https://context7.com/almindor/mipidsi/llms.txt Creates an SPI display interface by wrapping an embedded-hal SpiDevice and a D/C OutputPin. It utilizes a mutable byte slice as an internal write buffer. ```APIDOC ## SpiInterface::new — Create an SPI display interface Wraps an `embedded-hal` `SpiDevice` and a D/C `OutputPin` into the `Interface` trait. A mutable byte slice is used as an internal write buffer; 512 bytes is a good starting size. `SpiInterface` uses `InterfaceKind::Serial4Line`. ```rust use mipidsi::interface::SpiInterface; use embedded_hal_bus::spi::ExclusiveDevice; // spi: impl SpiDevice (e.g. from embedded-hal-bus or rppal) // dc: impl OutputPin (Data/Command select) let spi_device = ExclusiveDevice::new_no_delay(spi, cs).unwrap(); let mut buffer = [0_u8; 512]; let di = SpiInterface::new(spi_device, dc, &mut buffer); // Release the peripherals back when done let (spi_device, dc) = di.release(); ``` ``` -------------------------------- ### Builder::new Source: https://context7.com/almindor/mipidsi/llms.txt Constructs a display builder for a given model and interface. This method initiates a fluent builder chain for configuring and initializing the display. ```APIDOC ## Builder::new — Construct a display builder for a given model `Builder::new(model, di)` creates a builder for any type implementing the `Model` trait, paired with an interface implementing `Interface`. All configuration methods consume and return `Self`, forming a fluent builder chain. Call `.init(&mut delay)` at the end to initialize the hardware and obtain a ready-to-use `Display`. ```rust use mipidsi::interface::SpiInterface; use mipidsi::{Builder, models::ILI9486Rgb666}; use mipidsi::options::{ColorOrder, ColorInversion, Orientation, Rotation}; use embedded_graphics::pixelcolor::Rgb666; // Allocate the SPI transmit buffer (larger = faster, at cost of RAM) let mut buffer = [0_u8; 512]; // Create the SPI interface from an embedded-hal SpiDevice, a D/C pin, and the buffer let di = SpiInterface::new(spi, dc, &mut buffer); // Build and initialize the display driver // .reset_pin(rst) – optional hardware reset pin (must start HIGH) // .color_order(...) – RGB or BGR subpixel order // .invert_colors(...) – Normal or Inverted color output // .display_size(w, h) – override framebuffer active area (pixels) // .display_offset(x,y) – shift active area within the controller framebuffer // .orientation(...) – initial rotation / mirror let mut display = Builder::new(ILI9486Rgb666, di) .reset_pin(rst) .color_order(ColorOrder::Bgr) .invert_colors(ColorInversion::Normal) .display_size(480, 320) .display_offset(0, 0) .orientation(Orientation::new().rotate(Rotation::Deg0)) .init(&mut delay) .unwrap(); // display is now awake and ready; no need to call wake() display.clear(Rgb666::BLACK).unwrap(); ``` ``` -------------------------------- ### Cargo.toml Dependency Configuration Source: https://context7.com/almindor/mipidsi/llms.txt Minimal dependency configuration for the mipidsi crate. Shows how to include the crate with default features or with specific features like `defmt` enabled and default features disabled. ```toml # Cargo.toml — minimal dependency [dependencies] mipidsi = "0.10" # With defmt logging support, without draw batching [dependencies] mipidsi = { version = "0.10", default-features = false, features = ["defmt"] } ``` -------------------------------- ### Use Builder::reset_pin setter instead of init parameter Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md The reset pin parameter has been removed from `Builder::init`. Use the `Builder::reset_pin` setter method instead to configure the reset pin. ```rust use mipidsi::Builder; let display = Builder::new(ili9341_rgb565, di) .init(&mut delay, Some(rst))?; ``` ```rust use mipidsi::{Builder, models::ILI9341Rgb565}; let display = Builder::new(ILI9341Rgb565, di) .reset_pin(rst) .init(&mut delay)?; ``` -------------------------------- ### Display Power Management (Sleep/Wake) Source: https://context7.com/almindor/mipidsi/llms.txt Manages display power states using EnterSleepMode and ExitSleepMode commands, including a mandatory delay. Use `is_sleeping()` to check the current state before drawing. ```rust use embedded_hal::delay::DelayNs; // Put display to sleep (reduces power consumption) display.sleep(&mut delay).unwrap(); assert!(display.is_sleeping()); // Wake the display before issuing further draw calls display.wake(&mut delay).unwrap(); assert!(!display.is_sleeping()); // Normal drawing resumes immediately display.clear(Rgb565::BLACK).unwrap(); ``` -------------------------------- ### ParallelInterface::new Source: https://context7.com/almindor/mipidsi/llms.txt Creates an 8080-style parallel display interface, wrapping an OutputBus, a D/C pin, and a WR pin. Supports 8-bit or 16-bit buses. ```APIDOC ## ParallelInterface::new — Create an 8080-style parallel display interface Wraps an `OutputBus` (8-bit or 16-bit), a D/C pin, and a WR (write-enable) pin. `Generic8BitBus` and `Generic16BitBus` implement `OutputBus` from tuples of `OutputPin`s. The first pin in the tuple is the least-significant bit. ```rust use mipidsi::interface::{Generic8BitBus, ParallelInterface}; use mipidsi::{Builder, models::ILI9341Rgb666}; use mipidsi::options::ColorOrder; use embedded_graphics::pixelcolor::Rgb666; // Eight GPIO output pins for the 8-bit data bus (LSB first) let bus = Generic8BitBus::new((d0, d1, d2, d3, d4, d5, d6, d7)); // ParallelInterface(bus, dc_pin, wr_pin) let di = ParallelInterface::new(bus, dc, wr); let mut display = Builder::new(ILI9341Rgb666, di) .reset_pin(rst) .color_order(ColorOrder::Bgr) .init(&mut delay) .unwrap(); display.clear(Rgb666::RED).unwrap(); // Deconstruct to recover bus and pins let (bus, dc, wr) = di.release(); // (if not moved into Builder) ``` ``` -------------------------------- ### InterfaceExt::write_command and InterfaceExt::write_raw Source: https://context7.com/almindor/mipidsi/llms.txt Enables sending typed DCS commands using the `DcsCommand` trait or raw command bytes. `write_command` serializes a typed command into bytes before sending, while `write_raw` sends arbitrary opcode and parameter bytes directly. Both require `unsafe` context due to potential state desynchronization. ```APIDOC ## DcsCommand / InterfaceExt::write_command — Send typed DCS commands The `DcsCommand` trait represents a typed MIPI DCS instruction. `InterfaceExt::write_command` serializes it to bytes and sends it over the interface. `write_raw` sends arbitrary opcode + parameter bytes. ```rust use mipidsi::dcs::{InterfaceExt, SetPixelFormat, PixelFormat, BitsPerPixel}; // Build a COLMOD (0x3A) command for 16-bit (RGB565) color let colmod = SetPixelFormat::new(PixelFormat::with_all(BitsPerPixel::Sixteen)); // Send via the interface (available through unsafe dcs()) unsafe { display.dcs().write_command(colmod).unwrap(); } // Send a raw instruction with inline parameters unsafe { display.dcs().write_raw(0xB1, &[0x00, 0x1B]).unwrap(); } ``` ``` -------------------------------- ### Compose Orientation Transforms Source: https://context7.com/almindor/mipidsi/llms.txt Combines rotation and mirroring transformations for display orientation. Transformations are applied sequentially. Includes conversion from degrees to Rotation and rotation of Rotation values. ```rust use mipidsi::options::{Orientation, Rotation}; // 90° clockwise, then flip vertically (relative to the new orientation) let o1 = Orientation::new().rotate(Rotation::Deg90).flip_vertical(); // Equivalent combination let o2 = Orientation::new().flip_horizontal().rotate(Rotation::Deg270); assert_eq!(o1, o2); // Convert degree integer → Rotation (fails for non-multiples of 90) let r = Rotation::try_from_degree(180).unwrap(); assert_eq!(r, Rotation::Deg180); // Rotate one Rotation by another let combined = Rotation::Deg90.rotate(Rotation::Deg90); assert_eq!(combined, Rotation::Deg180); ``` -------------------------------- ### Replace display_interface::PGPIO{8,16}BitInterface with mipidsi::interface::ParallelInterface Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md Migrate parallel GPIO interface usage by replacing `display_interface_parallel_gpio::{PGPIO8BitInterface, Generic8BitBus}` with `mipidsi::interface::{ParallelInterface, Generic8BitBus}`. Ensure the `Generic8BitBus` is correctly instantiated with the pins. ```rust use display_interface_parallel_gpio::Generic8BitBus; use display_interface_parallel_gpio::PGPIO8BitInterface; let bus = Generic8BitBus::new(pins); let di = PGPIO8BitInterface::new(bus, dc, wr); ``` ```rust use mipidsi::interface::Generic8BitBus; use mipidsi::interface::ParallelInterface; let bus = Generic8BitBus::new(pins); let di = ParallelInterface::new(bus, dc, wr); ``` -------------------------------- ### Display::sleep / Display::wake Source: https://context7.com/almindor/mipidsi/llms.txt Manages display power states by sending MIPI DCS `EnterSleepMode` / `ExitSleepMode` commands, including a mandatory delay. Use `is_sleeping()` to check the current state. ```APIDOC ## Display::sleep / Display::wake — Display power management Sends the MIPI DCS `EnterSleepMode` / `ExitSleepMode` commands followed by the mandatory 120 ms delay. Use `is_sleeping()` to guard against issuing drawing commands while the panel is in sleep mode. ### Request Example ```rust use embedded_hal::delay::DelayNs; // Put display to sleep (reduces power consumption) display.sleep(&mut delay).unwrap(); assert!(display.is_sleeping()); // Wake the display before issuing further draw calls display.wake(&mut delay).unwrap(); assert!(!display.is_sleeping()); // Normal drawing resumes immediately display.clear(Rgb565::BLACK).unwrap(); ``` ``` -------------------------------- ### Replace display_interface::SPIInterface with mipidsi::interface::SpiInterface Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md Update SPI interface usage by replacing `display_interface_spi::SPIInterface` with `mipidsi::interface::SpiInterface`. The new interface requires a mutable byte buffer for improved performance. ```rust use display_interface_spi::SPIInterface; let di = SPIInterface::new(spi_device, dc); ``` ```rust use mipidsi::interface::SpiInterface; let mut buffer = [0_u8; 512]; let di = SpiInterface::new(spi_device, dc, &mut buffer); ``` -------------------------------- ### SpiInterface::new — Create SPI Interface Source: https://context7.com/almindor/mipidsi/llms.txt Wraps an embedded-hal SpiDevice and a D/C OutputPin for SPI communication. A mutable byte slice is required for the internal write buffer. `SpiInterface` uses `InterfaceKind::Serial4Line`. ```rust use mipidsi::interface::SpiInterface; use embedded_hal_bus::spi::ExclusiveDevice; // spi: impl SpiDevice (e.g. from embedded-hal-bus or rppal) // dc: impl OutputPin (Data/Command select) let spi_device = ExclusiveDevice::new_no_delay(spi, cs).unwrap(); let mut buffer = [0_u8; 512]; let di = SpiInterface::new(spi_device, dc, &mut buffer); // Release the peripherals back when done let (spi_device, dc) = di.release(); ``` -------------------------------- ### Deconstruct Display Driver Source: https://context7.com/almindor/mipidsi/llms.txt Use this to reclaim hardware peripherals after the display is no longer needed. The SPI interface can also be released separately. ```rust let (di, _model, _rst) = display.release(); let (spi_device, dc_pin) = di.release(); ``` -------------------------------- ### TestImage Source: https://context7.com/almindor/mipidsi/llms.txt Provides a `TestImage` struct that implements `embedded_graphics_core::Drawable`. This allows rendering a diagnostic test pattern, including a white border, RGB color bars with labels, and a top-left white marker. Drawing this image is useful for verifying display orientation, color order, and offset settings. ```APIDOC ## TestImage — Diagnostic test pattern drawable `TestImage` implements `embedded_graphics_core::Drawable` and renders a calibration image: a 1-pixel white border, RGB color bars with labels, and a top-left triangular white marker. Draw it on the display to verify orientation, color order, and display offset settings. ```rust use mipidsi::TestImage; use embedded_graphics::{pixelcolor::Rgb565, prelude::*}; // Draw the test image onto the display to verify color/orientation settings TestImage::::new().draw(&mut display).unwrap(); // If colors are wrong, adjust color_order / invert_colors in the Builder. // If borders are clipped, adjust display_size / display_offset. // If the triangle is not top-left or text is mirrored, adjust orientation. ``` ``` -------------------------------- ### ParallelInterface::new — Create 8080-style Parallel Interface Source: https://context7.com/almindor/mipidsi/llms.txt Creates an 8080-style parallel interface using an OutputBus (8-bit or 16-bit), a D/C pin, and a WR pin. Generic8BitBus and Generic16BitBus can be created from tuples of OutputPins. ```rust use mipidsi::interface::{Generic8BitBus, ParallelInterface}; use mipidsi::{Builder, models::ILI9341Rgb666}; use mipidsi::options::ColorOrder; use embedded_graphics::pixelcolor::Rgb666; // Eight GPIO output pins for the 8-bit data bus (LSB first) let bus = Generic8BitBus::new((d0, d1, d2, d3, d4, d5, d6, d7)); // ParallelInterface(bus, dc_pin, wr_pin) let di = ParallelInterface::new(bus, dc, wr); let mut display = Builder::new(ILI9341Rgb666, di) .reset_pin(rst) .color_order(ColorOrder::Bgr) .init(&mut delay) .unwrap(); display.clear(Rgb666::RED).unwrap(); // Deconstruct to recover bus and pins let (bus, dc, wr) = di.release(); // (if not moved into Builder) ``` -------------------------------- ### Display::clear Source: https://context7.com/almindor/mipidsi/llms.txt Fills the entire display with a single color. This method implements `DrawTarget::fill_solid` and uses an efficient `send_repeated_pixel` path. ```APIDOC ## Display::clear — Fill the entire display with a single color Implements `DrawTarget::fill_solid` over the full bounding box. Uses the efficient `send_repeated_pixel` path to minimize bus transactions. ### Request Example ```rust use embedded_graphics::pixelcolor::{Rgb565, RgbColor}; // Fill entire screen with black display.clear(Rgb565::BLACK).unwrap(); // Fill with a custom color display.clear(Rgb565::new(31, 0, 0)).unwrap(); // max red ``` ``` -------------------------------- ### Set Display Orientation Source: https://context7.com/almindor/mipidsi/llms.txt Changes the display orientation and mirroring settings at runtime by updating the MADCTL register. Width and height are automatically swapped for 90°/270° rotations. ```rust use mipidsi::options::{Orientation, Rotation}; // Rotate 90° clockwise display.set_orientation(Orientation::new().rotate(Rotation::Deg90)).unwrap(); // Mirror horizontally in the current rotation display.set_orientation(Orientation::new().flip_horizontal()).unwrap(); // Read back current orientation let current = display.orientation(); assert_eq!(current.rotation, Rotation::Deg90); ``` -------------------------------- ### Display::set_vertical_scroll_region / set_vertical_scroll_offset Source: https://context7.com/almindor/mipidsi/llms.txt Configures hardware scrolling by defining a fixed-area/scroll-area/fixed-area partition and setting the scroll offset. ```APIDOC ## Display::set_vertical_scroll_region / set_vertical_scroll_offset — Hardware scrolling Defines a fixed-area / scroll-area / fixed-area partition in the framebuffer (in the display's default orientation, regardless of the current software rotation). Then `set_vertical_scroll_offset` shifts the scroll area upward by the given number of pixels. ### Request Example ```rust // For a 320-pixel-tall display: // Fixed top bar: 40 px, fixed bottom bar: 40 px, scroll area: 240 px display.set_vertical_scroll_region(40, 40).unwrap(); // Scroll up by 10 pixels let mut offset = 0u16; loop { offset = (offset + 1) % 240; display.set_vertical_scroll_offset(40 + offset).unwrap(); delay.delay_ms(16); } ``` ``` -------------------------------- ### Draw Diagnostic Test Image Source: https://context7.com/almindor/mipidsi/llms.txt Draws a calibration image to verify orientation, color order, and display offset settings. Adjust builder options if colors are wrong, borders are clipped, or the triangle is not top-left or text is mirrored. ```rust use mipidsi::TestImage; use embedded_graphics::{pixelcolor::Rgb565, prelude::*}; // Draw the test image onto the display to verify color/orientation settings TestImage::::new().draw(&mut display).unwrap(); // If colors are wrong, adjust color_order / invert_colors in the Builder. // If borders are clipped, adjust display_size / display_offset. // If the triangle is not top-left or text is mirrored, adjust orientation. ``` -------------------------------- ### Implement custom OutputBus trait for mipidsi Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md If you have a custom implementation of `display_interface_parallel_gpio::OutputBus`, replace it with `mipidsi::interface::OutputBus`. The new trait is identical except for its associated error type, which is no longer hardcoded to `display_interface::DisplayError`. ```rust pub struct FsmcAdapter(pub Lcd); impl Interface for FsmcAdapter where S: SubBank, WORD: Word + Copy + From, { type Word = WORD; type Error = Infallible; fn send_command(&mut self, command: u8, args: &[u8]) -> Result<(), Self::Error> { self.0.write_command(command.into()); for &arg in args { self.0.write_data(arg.into()); } Ok(()) } fn send_pixels( &mut self, pixels: impl IntoIterator, ) -> Result<(), Self::Error> { for pixel in pixels { for word in pixel { self.0.write_data(word); } } Ok(()) } fn send_repeated_pixel( &mut self, pixel: [Self::Word; N], count: u32, ) -> Result<(), Self::Error> { self.send_pixels((0..count).map(|_| pixel)) } } ``` -------------------------------- ### Clear Display with Color Source: https://context7.com/almindor/mipidsi/llms.txt Fills the entire display with a single color. Uses an efficient repeated pixel path. Supports both predefined and custom RGB565 colors. ```rust use embedded_graphics::pixelcolor::{Rgb565, RgbColor}; // Fill entire screen with black display.clear(Rgb565::BLACK).unwrap(); // Fill with a custom color display.clear(Rgb565::new(31, 0, 0)).unwrap(); // max red ``` -------------------------------- ### Use generic Builder::new constructor instead of model-specific constructors Source: https://github.com/almindor/mipidsi/blob/master/docs/MIGRATION.md In version 0.8, model-specific constructors like `Builder::ili9341_rgb565` have been removed. Use the generic `Builder::new` constructor, passing the model struct (e.g., `ILI9341Rgb565`) as the first argument. ```rust use mipidsi::Builder; let display = Builder::ili9341_rgb565(di) .init(&mut delay, None)?; ``` ```rust use mipidsi::{Builder, models::ILI9341Rgb565}; let display = Builder::new(ILI9341Rgb565, di) .init(&mut delay)?; ``` -------------------------------- ### Display::set_orientation Source: https://context7.com/almindor/mipidsi/llms.txt Changes the display orientation at runtime by updating the MADCTL register. Width and height are automatically swapped for 90°/270° rotations. ```APIDOC ## Display::set_orientation — Change display orientation at runtime Updates the MADCTL register to reflect the new rotation and mirror settings. Width/height reported by `OriginDimensions::size()` are automatically swapped for 90°/270° rotations. ### Request Example ```rust use mipidsi::options::{Orientation, Rotation}; // Rotate 90° clockwise display.set_orientation(Orientation::new().rotate(Rotation::Deg90)).unwrap(); // Mirror horizontally in the current rotation display.set_orientation(Orientation::new().flip_horizontal()).unwrap(); // Read back current orientation let current = display.orientation(); assert_eq!(current.rotation, Rotation::Deg90); ``` ``` -------------------------------- ### Display::dcs Source: https://context7.com/almindor/mipidsi/llms.txt Provides unsafe access to the raw DCS (Display Command Set) interface. This method returns a mutable reference to the `DI` (Display Interface) allowing for the transmission of arbitrary raw DCS commands. It is marked `unsafe` because sending raw commands can potentially desynchronize the driver's internal state. ```APIDOC ## unsafe Display::dcs — Access the raw DCS interface Returns a `&mut DI` to send arbitrary raw DCS commands. Marked `unsafe` because raw commands can desynchronize the driver's internal state. ```rust use mipidsi::dcs::InterfaceExt; // SAFETY: we are only sending a display-off command and tracking state manually unsafe { display.dcs().write_raw(0x28, &[]).unwrap(); // SetDisplayOff } ``` ``` -------------------------------- ### Display::release Source: https://context7.com/almindor/mipidsi/llms.txt Deconstructs the display driver to reclaim the underlying SPI interface, model, and reset pin. This allows for reusing hardware peripherals after the display is no longer needed. ```APIDOC ## Display::release — Deconstruct the display driver Consumes the `Display` and returns the underlying interface, model, and optional reset pin. Use this to reclaim the hardware peripherals after the display is no longer needed. ```rust // Deconstruct the display to get back the SPI interface, model, and reset pin let (di, _model, _rst) = display.release(); // The SPI interface itself can also be released let (spi_device, dc_pin) = di.release(); ``` ``` -------------------------------- ### Access Raw DCS Interface Source: https://context7.com/almindor/mipidsi/llms.txt Returns a mutable reference to the DI to send arbitrary raw DCS commands. Marked unsafe because raw commands can desynchronize the driver's internal state. Use with caution and ensure state is manually tracked. ```rust use mipidsi::dcs::InterfaceExt; // SAFETY: we are only sending a display-off command and tracking state manually unsafe { display.dcs().write_raw(0x28, &[]).unwrap(); // SetDisplayOff } ``` -------------------------------- ### Send Typed DCS Commands Source: https://context7.com/almindor/mipidsi/llms.txt The `DcsCommand` trait represents a typed MIPI DCS instruction. `InterfaceExt::write_command` serializes it to bytes and sends it over the interface. `write_raw` sends arbitrary opcode + parameter bytes. ```rust use mipidsi::dcs::{InterfaceExt, SetPixelFormat, PixelFormat, BitsPerPixel}; // Build a COLMOD (0x3A) command for 16-bit (RGB565) color let colmod = SetPixelFormat::new(PixelFormat::with_all(BitsPerPixel::Sixteen)); // Send via the interface (available through unsafe dcs()) unsafe { display.dcs().write_command(colmod).unwrap(); } // Send a raw instruction with inline parameters unsafe { display.dcs().write_raw(0xB1, &[0x00, 0x1B]).unwrap(); } ``` -------------------------------- ### Display::set_tearing_effect Source: https://context7.com/almindor/mipidsi/llms.txt Configures the tearing-effect output pin to synchronize frame updates with the display refresh cycle, eliminating tearing. ```APIDOC ## Display::set_tearing_effect — Configure the tearing-effect output pin Enables or disables the TE output signal, which can be used to synchronize frame updates with the display refresh cycle to eliminate tearing. ### Request Example ```rust use mipidsi::options::TearingEffect; // Enable vertical blanking TE signal display.set_tearing_effect(TearingEffect::Vertical).unwrap(); // Enable both H and V blanking display.set_tearing_effect(TearingEffect::HorizontalAndVertical).unwrap(); // Disable TE output display.set_tearing_effect(TearingEffect::Off).unwrap(); ``` ``` -------------------------------- ### Hardware Vertical Scrolling Source: https://context7.com/almindor/mipidsi/llms.txt Configures hardware scrolling by defining a scrollable region within the framebuffer and setting the scroll offset. The region is defined in the display's default orientation. ```rust // For a 320-pixel-tall display: // Fixed top bar: 40 px, fixed bottom bar: 40 px, scroll area: 240 px display.set_vertical_scroll_region(40, 40).unwrap(); // Scroll up by 10 pixels let mut offset = 0u16; loop { offset = (offset + 1) % 240; display.set_vertical_scroll_offset(40 + offset).unwrap(); delay.delay_ms(16); } ``` -------------------------------- ### Set Rectangular Region of Pixels Source: https://context7.com/almindor/mipidsi/llms.txt Writes a rectangular region of pixels by setting the address window and consuming pixels from an iterator. For typical use, `fill_contiguous` from `embedded-graphics` is preferred. ```rust use embedded_graphics::pixelcolor::Rgb565; // Fill a 10×10 block at (20, 30) with alternating red/blue checkerboard let colors = (0u32..100).map(|i| { if (i / 10 + i % 10) % 2 == 0 { Rgb565::RED } else { Rgb565::BLUE } }); display.set_pixels(20, 30, 29, 39, colors).unwrap(); ``` -------------------------------- ### Display::set_pixels Source: https://context7.com/almindor/mipidsi/llms.txt Writes a rectangular region of pixels. The address window is set to `[sx, ex] × [sy, ey]` (inclusive), and pixels are consumed from an iterator. ```APIDOC ## Display::set_pixels — Write a rectangular region of pixels Low-level bulk pixel write. The address window is set to `[sx, ex] × [sy, ey]` (inclusive) and pixels are consumed from the iterator row by row, top-left to bottom-right. Prefer `fill_contiguous` from `embedded-graphics` for typical use. ### Request Example ```rust use embedded_graphics::pixelcolor::Rgb565; // Fill a 10×10 block at (20, 30) with alternating red/blue checkerboard let colors = (0u32..100).map(|i| { if (i / 10 + i % 10) % 2 == 0 { Rgb565::RED } else { Rgb565::BLUE } }); display.set_pixels(20, 30, 29, 39, colors).unwrap(); ``` ``` -------------------------------- ### Orientation Source: https://context7.com/almindor/mipidsi/llms.txt A value type for composing rotation and mirror transforms. It combines a `Rotation` (0°/90°/180°/270°) and a `mirrored` flag. ```APIDOC ## Orientation — Compose rotation and mirror transforms `Orientation` is a value type combining a `Rotation` (0°/90°/180°/270°) and a `mirrored` flag. Transformations are applied in order; note that `rotate` then `flip` is not the same as `flip` then `rotate`. ### Request Example ```rust use mipidsi::options::{Orientation, Rotation}; // 90° clockwise, then flip vertically (relative to the new orientation) let o1 = Orientation::new().rotate(Rotation::Deg90).flip_vertical(); // Equivalent combination let o2 = Orientation::new().flip_horizontal().rotate(Rotation::Deg270); assert_eq!(o1, o2); // Convert degree integer → Rotation (fails for non-multiples of 90) let r = Rotation::try_from_degree(180).unwrap(); assert_eq!(r, Rotation::Deg180); // Rotate one Rotation by another let combined = Rotation::Deg90.rotate(Rotation::Deg90); assert_eq!(combined, Rotation::Deg180); ``` ``` -------------------------------- ### Set Single Pixel Source: https://context7.com/almindor/mipidsi/llms.txt Writes a single pixel at the specified logical coordinates (x, y) using the given color. No bounds checking is performed, so out-of-bounds coordinates result in undefined behavior. ```rust use embedded_graphics::pixelcolor::Rgb565; // Draw a single yellow pixel at logical position (100, 200) display.set_pixel(100, 200, Rgb565::new(31, 63, 0)).unwrap(); ``` -------------------------------- ### Display::set_pixel Source: https://context7.com/almindor/mipidsi/llms.txt Writes a single pixel at the specified (x, y) coordinates without changing the current address window. Coordinates are in the logical space of the current orientation. ```APIDOC ## Display::set_pixel — Write a single pixel at (x, y) Sets one pixel without changing the current address window. Coordinates are in the current orientation's logical space (after rotation/mirror). Out-of-bounds coordinates produce undefined behavior—no bounds checking is performed. ### Request Example ```rust use embedded_graphics::pixelcolor::Rgb565; // Draw a single yellow pixel at logical position (100, 200) display.set_pixel(100, 200, Rgb565::new(31, 63, 0)).unwrap(); ``` ``` -------------------------------- ### Configure Tearing Effect Output Source: https://context7.com/almindor/mipidsi/llms.txt Enables or disables the TE (Tearing Effect) output signal to synchronize frame updates with the display refresh cycle, preventing visual tearing. Supports vertical, horizontal+vertical, or disabling the signal. ```rust use mipidsi::options::TearingEffect; // Enable vertical blanking TE signal display.set_tearing_effect(TearingEffect::Vertical).unwrap(); // Enable both H and V blanking display.set_tearing_effect(TearingEffect::HorizontalAndVertical).unwrap(); // Disable TE output display.set_tearing_effect(TearingEffect::Off).unwrap(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.