Xinyuan-LilyGO / T-Display-S3

MIT License
733 stars 174 forks source link

Simple hello world example in RUST? #160

Closed milewski closed 1 year ago

milewski commented 1 year ago

Does anyone have a basic hello world example of working with the display written in RUST?

I have no clue what is wrong with the example below, I suspect I have mapped the pins incorrectly, but I find no reference of what they should be anywhere online for this specific hardware:

fn main() -> anyhow::Result<()> {
    esp_idf_sys::link_patches();

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

    let backlight = peripherals.pins.gpio38; // Pretty sure this one is correct
    let dc = peripherals.pins.gpio7;         // no idea what DC standards for... direct current?
    let cs = peripherals.pins.gpio6;         // Im in doubt if this is right.. or should it be GPIO10?    
    let rst = peripherals.pins.gpio5;        // No idea what RST stands for... mapped to LCD_RES (Resolution?)
    let spi = peripherals.spi2;              // I don't know if I should use SPI2 or 3 
    let sclk = peripherals.pins.gpio12;      // No idea what Something Clock? should map to.. so my guess was SPI_CLK
    let sdo = peripherals.pins.gpio11;       // Clueless... no mention of what SDO means anywhere on everywhere I look

    let mut backlight = PinDriver::output(backlight)?;
    backlight.set_high()?;                   // Geat! The backlight turns on when I run the code

    let di = SPIInterfaceNoCS::new(          // Found this example here: https://github.com/ivmarkov/rust-esp32-std-demo/blob/50ab64ed4bf51f02807864458e096c595b94cc1c/src/main.rs#L1045-L1071
        spi::SpiDeviceDriver::new_single(
            spi,
            sclk,
            sdo,
            Option::<gpio::AnyIOPin>::None,
            Some(cs),
            &spi::SpiDriverConfig::new(),
            &spi::SpiConfig::new()
        )?,
        gpio::PinDriver::output(dc)?,
    );

    let mut display = mipidsi::Builder::st7789(di)
        .init(&mut delay::Ets, Some(PinDriver::output(rst)?))
        .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;

    display.clear(RgbColor::RED).unwrap();   // have tried various ways of drawing anything to screen but LCD always black

    loop {

    }
}
milewski commented 1 year ago

Figured it out:

fn main() -> anyhow::Result<()> {
    esp_idf_sys::link_patches();

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

    let mut backlight = PinDriver::output(peripherals.pins.gpio38)?;
    let dc = PinDriver::output(peripherals.pins.gpio7)?;
    let mut cs = PinDriver::output(peripherals.pins.gpio6)?;
    let mut rst = PinDriver::output(peripherals.pins.gpio5)?;
    let wr = PinDriver::output(peripherals.pins.gpio8)?;
    let mut rd = PinDriver::output(peripherals.pins.gpio9)?;

    backlight.set_high()?;

    // set to low to enable display
    cs.set_low()?;

    // set to high when not in use
    rd.set_high()?;

    let mut d0 = PinDriver::output(peripherals.pins.gpio39)?;
    let mut d1 = PinDriver::output(peripherals.pins.gpio40)?;
    let mut d2 = PinDriver::output(peripherals.pins.gpio41)?;
    let mut d3 = PinDriver::output(peripherals.pins.gpio42)?;
    let mut d4 = PinDriver::output(peripherals.pins.gpio45)?;
    let mut d5 = PinDriver::output(peripherals.pins.gpio46)?;
    let mut d6 = PinDriver::output(peripherals.pins.gpio47)?;
    let mut d7 = PinDriver::output(peripherals.pins.gpio48)?;

    let bus = Generic8BitBus::new((d0, d1, d2, d3, d4, d5, d6, d7))
        .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;

    let di = PGPIO8BitInterface::new(bus, dc, wr);

    let mut display = mipidsi::Builder::st7789(di)
        .with_display_size(170, 320)
        .with_invert_colors(ColorInversion::Inverted)
        .init(&mut delay::FreeRtos, Some(rst))
        .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;

    display.clear(RgbColor::RED)
        .map_err(|e| anyhow::anyhow!("Display error: {:?}", e))?;

    loop {

    }
}
StefanWerW commented 10 months ago

Hi @milewski, I have followed your example and it also worked for me, but it is extremely slow, around 1fps. Any ideas?

milewski commented 10 months ago

Hi @StefanWerW yeah, I had the same issue, I posted this same question on another repo https://github.com/ivmarkov/rust-esp32-std-demo/issues/152#issuecomment-1595817789 and got some clue of what could be the issue (bit-banging) and there was a suggestion to switch to DMA...

I did not go further down this path yet, but I am going to be revisiting this soon, if you find a solution first please share :)

psytraxx commented 7 months ago

@milewski -thanks so much for sharing your solution - i followed your example and the screen is cut off -did you experience the same problem ?
Text::with_baseline("Hello world", Point::zero(), text_style, Baseline::Top) basically prints "o world"

milewski commented 7 months ago

It wasn't cut off on my on tests, it was just slowwww... maybe you got a different version?

dunef-io commented 5 months ago

You need to start the code with 'cargo espflash flash --monitor --release', or add

[profile.dev]
opt-level = 1 #  a number in the range of 1-3

to your Cargo.toml file. The optimization level makes a huge difference in the execution performance.