almindor / mipidsi

MIPI Display Serial Interface unified driver
MIT License
108 stars 46 forks source link

Inverted Colors with ST7735 Display #33

Closed cdsupina closed 1 year ago

cdsupina commented 1 year ago

I'm using a 128x160 ST7735 display and I'm noticing that the colors appear to be inverted.

display.clear(Rgb565::WHITE); makes the whole display black, display.set_pixels(1, 1, 10, 10, core::iter::repeat(Rgb565::YELLOW).take(100)); draws a 10x10 red square display.set_pixel(11, 11, Rgb565::RED); draws a single yellow pixel at coordinate (11, 11)

I think that I am setting up the display correctly, below is the code used to create the display as shown in the attached image.

fn main() -> anyhow::Result<()> {
    // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once,
    // or else some patches to the runtime implemented by esp-idf-sys might not link properly.
    esp_idf_sys::link_patches();

    let peripherals = Peripherals::take().unwrap();

    let sdo = peripherals.pins.gpio7;
    let sclk = peripherals.pins.gpio6;
    //let cs = peripherals.pins.gpio10;
    let a0 = peripherals.pins.gpio8.into_output()?; // dc
    let rst = peripherals.pins.gpio9.into_output()?;

    let spi = Master::<SPI2, _, _, Gpio2<Unknown>, Gpio10<Unknown>>::new(
        peripherals.spi2,
        Pins {
            sclk,
            sdo,
            sdi: None,
            cs: None,
        },
        //Config::default().baudrate(20_000_000.Hz()),
        Config {
            baudrate: 60_000_000.Hz(),
            write_only: true,
            ..Default::default()
        },
    )?;

    let di = display_interface_spi::SPIInterfaceNoCS::new(spi, a0);
    let mut display = mipidsi::Builder::st7735s(di)
        .with_display_size(128, 160)
        .with_framebuffer_size(128, 160)
        .with_color_order(mipidsi::ColorOrder::Rgb)
        .with_orientation(mipidsi::Orientation::Portrait(false))
        .init(&mut Ets, Some(rst))
        .unwrap();

    display.clear(Rgb565::WHITE);

    display.set_pixels(1, 1, 10, 10, core::iter::repeat(Rgb565::YELLOW).take(100));
    display.set_pixel(11, 11, Rgb565::RED);

    Ok(())
}

IMG_20221101_192624

almindor commented 1 year ago

That's an odd combination of color switching. What happens if you use ColorOrder::Bgr?

cdsupina commented 1 year ago

I changed the color mode to BGR:

...
.with_color_order(mipidsi::ColorOrder::Bgr)
...

It looks after changing that line of code, the large square changed to dark blue and the pixel turned to a light blue or cyan color.

IMG_20221102_195703

almindor commented 1 year ago

This is really odd. I've had things like Rgb/Bgr inverted before, but not this kind of odd shift. If you do Rgb again, can you try drawing "red" then "green" then "blue" squares in different places to see what comes up? I'm trying to wrap my head around what the "transformation" is.

rfuest commented 1 year ago

Maybe this has something to do with it? https://github.com/almindor/mipidsi/blob/master/src/models/st7735s.rs#L39-L40

almindor commented 1 year ago

Maybe this has something to do with it? https://github.com/almindor/mipidsi/blob/master/src/models/st7735s.rs#L39-L40

Good find, I'm not sure why the model author put that there twice, I'm guessing it's just a C&P bug.

@cdsupina could you please check out PR #34 to see if things work with that? I don't have this model to test with.

rfuest commented 1 year ago

There must be something else that's causing this issue. With my display the master branch outputs the correct colors and removing the INVON command causes the display to be inverted.

almindor commented 1 year ago

There must be something else that's causing this issue. With my display the master branch outputs the correct colors and removing the INVON command causes the display to be inverted.

Hmm then it's really odd. I'll remove the duplicate call in master at least.

almindor commented 1 year ago

@rfuest could you check with current master, just to be 100% sure that the double invon didn't cause some odd behaviour.

rfuest commented 1 year ago

The current master version works as expected.

I did some research and found that some code that contains INVON in the init sequence and other code doesn't. This might just need to be a configuration option.

rfuest commented 1 year ago

The datasheet contains this sentence in the features section: -Support both normal-black & normal-white LC. Maybe this is the reason the display inversion feature exists.

almindor commented 1 year ago

The current master version works as expected.

I did some research and found that some code that contains INVON in the init sequence and other code doesn't. This might just need to be a configuration option.

Good point. I don't think the colors @cdsupina sees are "correct" in either setting so I'll keep this issue and make a separate one for the invert move to options/builder.

rfuest commented 1 year ago

I don't think the colors @cdsupina sees are "correct" in either setting so I'll keep this issue and make a separate one for the invert move to options/builder.

OK, makes sense. I think that removing INVON and setting the color order to Bgr should result in the correct colors in their case.

cdsupina commented 1 year ago

My testing confirms what @rfuest says. Using the st7735s_uninverse branch and changing the color order to BGR makes the display appear as it should.

almindor commented 1 year ago

My testing confirms what @rfuest says. Using the st7735s_uninverse branch and changing the color order to BGR makes the display appear as it should.

Good to hear, thanks for confirming. I will try and create a fix for #35 so this can be configured properly.