almindor / mipidsi

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

ILI9341 not working with RPI Pico #64

Closed Slushee-a closed 11 months ago

Slushee-a commented 11 months ago

I wanted to drive the ILI9341 display with a Raspberry Pi Pico using the mipidsi crate, but it doesn't work. The screen stays white. I've searched the internet to try to find what my problem is but I couldn't find anything. The documentation is also very limited and there are no code examples (the one in the docs isn't even correct, .init() returns a result) and no wiring examples.

It's probably not working because I might have missed something from the docs or wired something wrong. But I can't for the life of me figure out where the problem is.

I used this carrier board » with this wiring ».

Here is a table with the connections, in case my drawing of the wiring isn't clear enough: Board Standard Reasoning Connected to Function
LCD_RD SPI MOSI RD = Read GP15 SPI TX (MOSI)
LCD_WR SPI MISO WR = Write GP12 SPI RX (MISO)
LCD_RS D/C Guess GP14 Digital out
LCD_CS CS CS = Chip Select GP13 Digital out
LCD_RST RESET RST = Reset GP11 Digital out
5V VSYS
3V3 3V3 (OUT)
GND GND

This is the code I used: Snippet »

If on the loop I add the following:

loop {
    display.clear(Rgb666::BLUE).unwrap();
    delay.delay_ms(100);
}
The oscilloscope reads the following: Red Blue
Clock MOSI

image

Red Blue
Clock MISO

image

The MOSI pin doesn't seem to be sending any important data, and the signal on the MISO pin looks really weird.

EDIT: When I touch the provided stylus to the display the MISO pin changes the output:

image

It seems the "Floor" of the signal is dependent on where I place the stylus on the screen.

Have you spotted any issue with my code or wiring? What else can I try to do to troubleshoot this issue?

If there is any information missing from this issue that you think might be helpful to troubleshoot it please do ask for it and I'll do my best to provide it.

rfuest commented 11 months ago

The module you are using seems to default to using a parallel bus and not SPI. At least I think it does according to the docs I found here: http://www.lcdwiki.com/2.4inch_Arduino_Display Unfortunately there doesn't seem to be a schematic for that module to confirm this.

You could either try to use a parallel bus from the Pico to the module or try to change the module to use SPI instead. R1/R2 might be a jumper to configure the communication protocol, but that is just a guess without access to the schematic.

Slushee-a commented 11 months ago

It seems like moving the resistor from R2 to R1 doesn't do anything. I'll try using the parallel port with display-interface-parallel-gpio instead and update with results.

rfuest commented 11 months ago

I just realized that not all connections necessary to run the display in SPI mode are available at the pins and parallel will be your only option.

rfuest commented 11 months ago

Another thing you should check is if the 3V3 pin on the module is connected to the output of the AMS1117 voltage regulator. If that is the case I would recommend to remove the connection from the 3V3 pin on the Pico to the module.

almindor commented 11 months ago

The documentation is also very limited and there are no code examples (the one in the docs isn't even correct, .init() returns a result) and no wiring examples.

When you have the time, could you please open a separate issue with specific places where you found the documentation either wrong (e.g. the init), or insufficient? I'd like to address them. I don't want to derail the thread here as it seems @rfuest has a good idea of what the issue might be.

Slushee-a commented 11 months ago

The 3V3 pin doesn't seem to be connected anywhere actually. Not to the voltage regulator, not to any of the pins on U2 and U3. Connecting or disconnecting it doesn't seem to make any difference.

I tried the parallel port:

    let mut rst = pins.gpio7.into_push_pull_output_in_state(gpio::PinState::High);
    let mut dc = pins.gpio6.into_push_pull_output();
    let mut wr = pins.gpio5.into_push_pull_output_in_state(gpio::PinState::Low);
    let mut lcd_d0 = pins.gpio15.into_push_pull_output();
    let mut lcd_d1 = pins.gpio14.into_push_pull_output();
    let mut lcd_d2 = pins.gpio13.into_push_pull_output();
    let mut lcd_d3 = pins.gpio12.into_push_pull_output();
    let mut lcd_d4 = pins.gpio11.into_push_pull_output();
    let mut lcd_d5 = pins.gpio10.into_push_pull_output();
    let mut lcd_d6 = pins.gpio9.into_push_pull_output();
    let mut lcd_d7 = pins.gpio8.into_push_pull_output();

    let bus = Generic8BitBus::new((lcd_d0, lcd_d1, lcd_d2, lcd_d3, lcd_d4, lcd_d5, lcd_d6, lcd_d7)).unwrap();
    let di = PGPIO8BitInterface::new(bus, dc, wr);

    let mut display = Builder::ili9341_rgb666(di).init(&mut delay, Some(rst)).unwrap();

    display.clear(Rgb666::RED).unwrap();

    loop {
        display.clear(Rgb666::RED).unwrap();
        delay.delay_ms(1000);
    }
Display pin Pico pin Function
GP15 LCD_D0 Parallel 0
GP14 LCD_D1 Parallel 1
GP13 LCD_D2 Parallel 2
GP12 LCD_D3 Parallel 3
GP11 LCD_D4 Parallel 4
GP10 LDC_D5 Parallel 5
GP9 LCD_D6 Parallel 6
GP8 LCD_D7 Parallel 7
GP7 LCD_RST Reset
GP6 LCD_RS Data selection
GP5 LCD_WR Write signal

It still doesn't seem to work. It dims down for a few milliseconds every second, presumably when data is being sent to it.

EDIT: The voltage on the VSYS pin drops from 4.02V to 3.95 when that happens. Should I maybe power the display externally?

rfuest commented 11 months ago

The 3V3 pin doesn't seem to be connected anywhere actually. Not to the voltage regulator, not to any of the pins on U2 and U3. Connecting or disconnecting it doesn't seem to make any difference.

Strange. Did you check the supply voltage on U2 and U3?

EDIT: The voltage on the VSYS pin drops from 4.02V to 3.95 when that happens. Should I maybe power the display externally?

Are you powering everything from the USB connection to the Pico? I've successfully powered displays from a Pico this way, but I used VBUS instead of VSYS.

rfuest commented 11 months ago

You need to pull the LCD_RD pin to high and change the init for the WR pin to be high initially. Both pins are active low and leaving RD floating might cause a bus conflict.

Slushee-a commented 11 months ago

Oh my gosh that worked! Thank you ever so much! The only issue now seems to be that the color is blue instead of red. (The R and B channels seem to be flipped?) Using VSYS and VBUS doesn't seem to make any difference. Connecting the display to an external 5V supply obviously yielded the best results.

And in reply to @almindor: Is it okay if I open a pull request improving the docs as far as my abilities allow me to? I will also add a list of all the pages of the docs I am not able to better document on the text of the PR. React with :+1: / :-1: to let me know

rfuest commented 11 months ago

Oh my gosh that worked! Thank you ever so much!

Nice, I'm glad that I could help.

The only issue now seems to be that the color is blue instead of red.

You can fix that by using https://docs.rs/mipidsi/latest/mipidsi/struct.Builder.html#method.with_color_order, with the Bgr color order.

almindor commented 11 months ago

And in reply to @almindor: Is it okay if I open a pull request improving the docs as far as my abilities allow me to? I will also add a list of all the pages of the docs I am not able to better document on the text of the PR. React with +1 / -1 to let me know

sure thing!