pm-kit: send ST7796 extension init (0xB6 480 lines) mipidsi omits

mipidsi's ST7796 model uses the ST7789 init, which skips the ST7796-specific
extension-command unlock (0xF0) and Display Function Control (0xB6 = 480 driving
lines) — so the panel only scanned part of the screen (image confined to a corner
region + snow). After mipidsi's init, send the missing commands via Display::dcs()
using the known-good values from the CircuitPython st7796_init.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-31 21:32:08 -05:00
parent 17d2aa134d
commit 0c8f370a5c

View file

@ -17,7 +17,7 @@ use embedded_graphics::{
use embedded_hal::delay::DelayNs;
use embedded_hal::digital::OutputPin;
use embedded_hal_bus::spi::ExclusiveDevice;
use mipidsi::interface::SpiInterface;
use mipidsi::interface::{Interface, SpiInterface};
use mipidsi::models::ST7796;
use mipidsi::options::{ColorInversion, ColorOrder, Orientation};
use mipidsi::Builder;
@ -85,6 +85,26 @@ fn main() -> ! {
.init(&mut timer)
.unwrap();
// ST7796-specific setup that mipidsi's ST7789-based init omits. The critical one is 0xB6
// (Display Function Control → 480 driving lines); without it the panel only scans part of
// the screen. Sequence + values from the working CircuitPython firmware (st7796_init).
{
let di = unsafe { display.dcs() };
di.send_command(0xF0, &[0xC3]).unwrap(); // unlock extension command set
di.send_command(0xF0, &[0x96]).unwrap();
di.send_command(0xB4, &[0x01]).unwrap(); // 1-dot inversion
di.send_command(0xB6, &[0x80, 0x02, 0x3B]).unwrap(); // display function control: 480 lines
di.send_command(0xE8, &[0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33]).unwrap();
di.send_command(0xC1, &[0x06]).unwrap();
di.send_command(0xC2, &[0xA7]).unwrap();
di.send_command(0xC5, &[0x18]).unwrap();
di.send_command(0xE0, &[0xF0, 0x09, 0x0B, 0x06, 0x04, 0x15, 0x2F, 0x54, 0x42, 0x3C, 0x17, 0x14, 0x18, 0x1B]).unwrap();
di.send_command(0xE1, &[0xE0, 0x09, 0x0B, 0x06, 0x04, 0x03, 0x2B, 0x43, 0x42, 0x3B, 0x16, 0x14, 0x17, 0x1B]).unwrap();
di.send_command(0xF0, &[0x3C]).unwrap(); // lock
di.send_command(0xF0, &[0x69]).unwrap();
}
timer.delay_ms(120);
let w = WIDTH as i32;
let h = HEIGHT as i32;
let m = 36; // marker size