Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime detection of Display Pack variant #1004

Open
Slion opened this issue Sep 28, 2024 · 21 comments
Open

Runtime detection of Display Pack variant #1004

Slion opened this issue Sep 28, 2024 · 21 comments

Comments

@Slion
Copy link

Slion commented Sep 28, 2024

I was wondering if it's possible to detect at runtime which Display Pack model is connected? Right now I'm using a compilation option to switch between large and small Display Pack.

Apparently it could be doable:
pimoroni/pico-boilerplate#20 (comment)

Display driver ST7789 datasheets.

Looking at the Pimoroni code that RDDID (04h): Read Display ID command has not been implemented.

@peardox
Copy link

peardox commented Sep 28, 2024

Looking at the Pimoroni code that RDDID (04h): Read Display ID command has not been implemented.

No, there are a several interesting ST7789 instructions missing including one that does vertical scroll (actually it's more or a vertical rotate but...). Looking at the code it has signs it was specifically written for one of the earlier displays then added to for new LCD sizes which is a little worrying.

Still going thru the datasheet (it's 319 pages) but it also appears we could simulate a text display. OK, not an overly astonishing revelation, but the buffer required would be tiny where you only needed to show N out of M symbols - which is a useful option IMHO

@Slion
Copy link
Author

Slion commented Sep 29, 2024

also appears we could simulate a text display.

Another interesting find, I won't bother with it just now though. In the context of stdio it's definitely something that could be used to improve the frame rate.

@Slion
Copy link
Author

Slion commented Sep 29, 2024

I tried to implement that RDDID command but I've never used SPI before and sure enough I could not get it working. None of the commands from Pimoroni driver are doing any read operation on SPI.
I tried to use spi_read_blocking without luck so far. All it reads is zeros.

Attempted a bunch of stuff around those lines:

    gpio_put(dc, 0); // command mode
    gpio_put(cs, 0);

    uint8_t commandId = 0x04;

    spi_write_blocking(spi, &commandId, 1);

    sleep_ms(1);

    gpio_put(dc, 1);
    //gpio_put(display.cs, 1);

    int read = spi_read_blocking(spi,0x00,rddid,sizeof(rddid));

    //int read = spi_write_read_blocking(display.spi,&commandId,rddid,1);

    gpio_put(cs, 1);

I found that but it did not help me much: https://github.com/prenticedavid/ST7789_kbv/blob/d5c7c3c18c9b3a37d9ae5891f0316ae1fe253b0f/examples/ST7789_readreg_diag/ST7789_readreg_diag.ino#L123

The truth is I really don't know what I'm doing here 🫣
It could also be that all those bits are just set to 0 on the Display Pack 2.0 I tested.

@peardox
Copy link

peardox commented Sep 29, 2024

Oh, rats. Checking the schematic the MISO pin isn't connected so the device is deliberately set up as write only - which, to be fair, was mentioned in the other thread

Same applies to both display packs

Not sure about 2.8 version as there's no schematic yet

Prevents anything read related then - pity, I fancied having a dump screen function but that's not possible with this wiring either.

There's a similar design by Waveshare that also is write-only. Their 3.5" touch (mine's almost here) display, however, does have MISO as does their 2.8 touch. Looks like it's dependant on a whim of the board supplier then...

@Slion
Copy link
Author

Slion commented Sep 29, 2024

Too bad that would have been useful. Something for Pimoroni to improve on next time they revise the hardware design, I guess. It's not like there is not enough pin on the Pico.

@peardox
Copy link

peardox commented Sep 29, 2024

Turns out it may still be possible....

Datasheet - 7.4.2 Serial Interface Characteristics (3-line serial)

This means it could work with the one data line - something to play with later once I've read some more and actually started writing some code for the thing (text with tiny frame buffer and rom fonts being the goal)

@Slion
Copy link
Author

Slion commented Sep 30, 2024

Datasheet - 7.4.2 Serial Interface Characteristics (3-line serial)

Sadly that's not telling me how the code should look like. If you want me to experiment with something and help me translate that diagram into code I'll be happy to give it a try though.

@Gadgetoid
Copy link
Member

Too bad that would have been useful. Something for Pimoroni to improve on next time they revise the hardware design, I guess. It's not like there is not enough pin on the Pico.

It is my understanding that, despite what the datasheet for the controller might say, the actual displays do not have these pins broken out on the ribbon cable.

Eg:

image

@peardox
Copy link

peardox commented Sep 30, 2024

Yeah, there's also Half Duplex SPI which only uses MOSI for data

Researching the subject ATM. Wiring illustration here - note it needs a resistor adding

Dunno if it'll work - hence lots of reading + watching before I even think of trying anything (to avoid killing something if possible)

Oops - won't work with a pack.... No way to do resistor - scratch that idea.

@Slion
Copy link
Author

Slion commented Sep 30, 2024

Dunno if it'll work - hence lots of reading + watching before I even think of trying anything (to avoid killing something if possible)

I did not know you could do things like that. Usually I try first and depending on the outcome go do some reading. The other day I killed a Display Pack with a heat-gun 😏

@peardox
Copy link

peardox commented Oct 2, 2024

I tried to implement that RDDID command but I've never used SPI before and sure enough I could not get it working.

In your test MOSI is set for output
After the command was sent you'd need MOSI to be input until the results had been fetched - then switch it back to output.

The board appears to be set up for bi-directional communication over that pin

i.e. you may have been attempting to read a write pin :)

@Slion
Copy link
Author

Slion commented Oct 3, 2024

In your test MOSI is set for output
After the command was sent you'd need MOSI to be input until the results had been fetched - then switch it back to output

How should I do that? Any code sample? I tried a bunch of things including switching to slave mode using spi_set_slave which would just crash and reboot.

The board appears to be set up for bi-directional communication over that pin

That would make a lot of sense since it avoids wasting one pin for some optional and rarely used functionality that only requires sending a few bytes.

@peardox
Copy link

peardox commented Oct 3, 2024

I had a bash at it in the early hours but no luck

From examination of the sdk it appears that only 'proper' full duplex mode is supported

The schematics show the settings of the st7789 IM0-2 pins but not IM3. Depending on whether IM3 is low (di-directional) or high (extra data bit) determines if read is possible at all - this info was gleaned from the 2.8 schematic (don't remember it being detailed on the others)

At one point I even hacked spi.c/h but didn't get anything working

Ticket to Pimoroni time to find out what the wiring is that they don't show.

It appears that everyone wires these things up this way. It's annoying as there are some nice things you can do with read access - there's even a vertical blank signal...

Then again VBL wouldn't help an amazing amount. The thruput to the LCD is already on the high side. Given the clocks available your theoretrical limit on a pico1 would be about 50FPS and it already does 30 so about 60% of the time we're just sending data to the screen

@peardox
Copy link

peardox commented Oct 3, 2024

Copy of ticket to support for information....

I have all the Pico Display packs and several other devices with displays such as enviro pack and display breakout.

Examining the Scematics for all these boards I am unable to tell how the ST7789s they all use are configured. The nearest I can get is from the display pack 2.0 which labels the states of IM0, IM1 and IM2 - this leaves IM3 unaccounted for. The difference in whether IM3 is low or high alters the workings of a ST7789 (we've got a lengthy discussion on github on exactly this topics) # 1004/1005

Would you kindly inform me of the wiring of IM3 so I can tell if something I'm attempting to do is possible or not in the first place (low = possible, high = impossible)

Also the display pack 2.8 is still marked as schematic coming soon - techie was on holiday (they're obvuisly back now so can we have that schematic pls)

@peardox
Copy link

peardox commented Oct 6, 2024

Some more information I've unearthed - finding this is a real nightmare, I know what I wanna do but not quite how to do it...:(

I believe the way to access RDDID etc is to NOT use the supplied SPI but instead use PIO to handle the SPI as this appears to offer the flexibility to allow reading and writing from the MOSI pin while the normal libs only allow writing via MOSI and reading via MISO

I eventially stumbled accress this...

https://github.com/raspberrypi/pico-examples/tree/master/pio/spi
Specifically spi.pio in that directory (which also mentions ST7789) so that leads us to...

https://github.com/raspberrypi/pico-examples/tree/master/pio/st7789_lcd
This does SPI using any old pins you desire which means that you could reverse the direction of the data to allow the pin usually assigned as MOSI to be read/write

The demo they have needs altering (trivially) to send data to a Display Pack - OK something we can already do with SPI BUT - re-writing the PIO SPI code SHOULD allow reads to be achieved over the same pin

While this will compilcate the code a little, specifically you'll need to switch between write and read modes, the end result should be equally performant to normal SPI whilst additionally giving access to the read functions of the ST7789

I think the benefits far outweigh the hassle involved in writing a replacement SPI driver as there are other useful functions in the read set of ST7789 instruction set (a good example would be a PRINT SCREEN or syncing to vertical blank...)

I'll get around to trying it out after I've sorted out some other stuff I wanna do beforehand (learning more about PIO being just one of the more important pre-requesites)

Conceptually I'd like to optionally hang on to the PIO block for as brief a time as possible as other things may want it.

@Slion
Copy link
Author

Slion commented Oct 6, 2024

Most interesting stuff, certainly a good excuse to dive into PIO. How is the standard SPI driver implemented? Is it not using PIO itself? Would it not be easier to modify and extend the standard driver to support half duplex 3 wires SPI?

Found this when searching for pico 3 wires spi.

@peardox
Copy link

peardox commented Oct 6, 2024

See the rp2040 daatasheet for full details but essentially when in SPI the device is hard-coded to 4 wire SPI with a FIFO on each of the MOSI + MISO pins which makes reading from the MISO (which is what we want to do) impossible.

3 pin SPI would require the slave/client device (LCD) to be set up to expect 3 wire. Packs are hard-wired to expect 4 wire SPI BUT the SPI they appear to use (almost certain even tho nothing back from support) looks like a 8/9 bit variant of 4 wire with 8-bit selected (going on the ST7789 datasheet anyway)

The display packs (and all other pre-assembled 7789 LCDs I've looked at) appear to use this 4 wire SPI. That specific version of SPI has the data pin configured for both input and output. i.e. the SPI is 'normal' when it comes to writing but non-standard when it comes to reading.

Unless you somewhat oddly desire the ability to read from a device you'd not usually use for anything other than writing therefore normal SPI would be easier to implement on the software side if available (which it invariably is). The available ST7789 drivers all appear to feature a subset of the possible features as a result

I guess that not many people other than us have asked the question regarding identifying the display info. It would appear to be such an uncommon feature that I find nothing even mentions it (maybe something I haven't read does...)

It should be born in mind that the read abaility is entirely theoretical ATM (it does however seem increasingly possible) - I will be emensley pleased if it turns out the concept is correct though...

@peardox
Copy link

peardox commented Oct 6, 2024

OK - a start (an extremely basic one)

Just adapted the pico example SPI using PIO to check it works - which it does

Configured for a Display Pack 2.0 / 2.8
It does nothing fancy - just rotates a graphic which test write via PIO rather than SPI
Indeed if you read the code you'll see that it doesn't use any SPI at all - everything's over PIO
Appears to run about 30FPS

The next (far harder) step is to figure out how to read from the display

https://github.com/PiPicoDev/st7789_pio

@Slion
Copy link
Author

Slion commented Oct 7, 2024

Cool stuff, shame you did not first commit the example from the SDK and then your changes. Would have been easier to see what was changed 😁

@peardox
Copy link

peardox commented Oct 7, 2024

Cool stuff, shame you did not first commit the example from the SDK and then your changes. Would have been easier to see what was changed 😁

Hardly changed anything but as the changes were so minimal it was easy to remember what I changed. Just updated repo to include comment // Altered for Display Pack 2.0 where changes were

About to add FPS code for it too - output to serial for simplicity

@peardox
Copy link

peardox commented Oct 7, 2024

See status report for updates on the experiment

Hint... Frame # 593 Time = 19727 us, FPS = 50.55

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants