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

How to figure out which controller is underneath the display? #40

Closed
Vvvsebastar opened this issue Oct 25, 2018 · 7 comments

Comments

@Vvvsebastar
Copy link

commented Oct 25, 2018

Hello,

I read the whole instructions and wanted to participate in your great work. I have just recently bought an Kedei 3.5 display (version 6.3 from August 2018) without HDMI. How can I figure out which controller is used?

Thanks
Sebastian

@juj

This comment has been minimized.

Copy link
Owner

commented Oct 26, 2018

Identifying a particular board can be tricky. If vendor does not advertise the chip, generally I look at the existing driver to the board, if one is provided by the vendor, and cross-reference that against the protocol sheet PDFs of the controller chips. In some cases, I have resorted to using a USB logic analyzer to reverse engineer the communication of a driver to find out what it matches up with.

3.5" 320x480 SPI displays that I have encountered have been either ILI9486, ILI9486L, HX8357D or MZ61581. There is also ILI9488 controller that is 320x480, although fbcp-ili9341 does not support that one, I have not come across a ILI9488 that would be sold as 4-wire SPI. I would guess the KeDei is either a ILI9486 or a ILI9486L, those seem to be the two most widely used chips. MZ61581 seems to no longer be in active production.

I have not attempted to visually identify any of the hardware circuitry on my boards. Let me know if finding the right controller is problematic, and I can look at posting photos of the displays I have, if that might help?

@Vvvsebastar

This comment has been minimized.

Copy link
Author

commented Oct 26, 2018

Thanks. I would really like to help with whatever I can to create a working version as the current "driver" and "OS-images" of the KeDei-website aren't well documentated nor work at all (for a RPi Zero).

Please find attached pictures of what I have in front of me.
front
back
open_display

@juj

This comment has been minimized.

Copy link
Owner

commented Oct 26, 2018

Good photos, the pins are conveniently marked in the display.

L_CS = Display Chip Select
T_CS = Touch Input Chip Select
IRQ = Touch Input Interrupt
CLK = SPI Clock
MISO = SPI Master In Slave Out
MOSI = SPI Master Out Slave In

Unfortunately the absence of Data/Control (DC) pin means that this is a 3-wire SPI instead of 4-wire SPI display. Currently fbcp-ili9341 does not support 3-wire SPI displays. 3-wire SPI displays interleave command/data control bit and payload bits in the MOSI line. That is, instead of using a separate DC line that goes high for Data, low for Command, during which the MOSI line sends 8 bits (or 16 bits depending on word width used) for the payload, 3-wire SPI displays interleave this information to one line as serial 9 bits (or 17 bits) of 1 bit D/C control, 8/16 bits payload, 1 bit D/C control, 8/16 bits payload, and so on.

This kind of interleaving has not been implemented. If you'd like to take a stab, this spot

would probably be a good place to start. You'd be looking at expanding the task->cmd byte to 9 bits with highest bit set to 0 to denote a command, lowest 8 bits set to the payload of task->cmd, followed by expanding the tStart .. tEnd array from 8 bits to 9 bits, padding in 1 bits between every byte. And then throughout the whole codebase, anything that refers to GPIO_TFT_DATA_CONTROL can be omitted, such as

CLEAR_GPIO(GPIO_TFT_DATA_CONTROL);

but everything is essentially payload bits as far as SPI messaging is concerned, and waiting for CS toggles do not need to be performed, as happens e.g. in

while(!(spi->cs & (BCM2835_SPI0_CS_RXD|BCM2835_SPI0_CS_DONE))) /*nop*/;

and somewhat more complex, in the DMA code in

disableTransferActive->dst = DMA_SPI_CS_PHYS_ADDRESS;

for anything that refers to DMA_SPI_CS_PHYS_ADDRESS. (Probably first pass of an implementation will want to disable DMA use altogether, DMA chaining with CS toggles is admittably very complex, because of technicalities that the BCM2835 DMA chip has)

@Vvvsebastar

This comment has been minimized.

Copy link
Author

commented Oct 26, 2018

Thanks for the very detailed explanation. I'm afraid that my programming knowledge doesn't reach that far into this topic to solve the work. Would you be interested in the display? For me it is quite worthless so that I would send it to you for free further development on this topic.

@juj

This comment has been minimized.

Copy link
Owner

commented Oct 26, 2018

Thank you for the most kind offer, it is much appreciated. However I am located in Finland, and it may not be worth the logistics to send the display over, because depending on where you live, customs may want to take part in the import, which may make it a pain. If you'd like to go ahead still, throw me a mail at jujjyl@gmail.com.

I should say I cannot promise that I'll be able to get the display working either even if you do send it. It might be easiest to get one of the detected working displays for a known good configuration.

@juj

This comment has been minimized.

Copy link
Owner

commented Nov 3, 2018

Noticed that my Adafruit SSD1351 display can be soldered to work in 3-wire mode instead of 4-wire mode, and I was able to add support to fbcp-ili9341 in 3-wire mode after modifying the display. The support is now up in above commit. If you still have the 3-wire SPI display, it may be possible that the above support could also work on the KeDei display, although I am still not sure what controller it has.

Also noticed there was an earlier conversation about KeDei at #27.

juj added a commit that referenced this issue Nov 25, 2018
Backup code, first working version to get KeDei Raspberry Pi 3.5 inch…
… SPI TFTLCD 480*320 16bit/18bit version 6.3 2018/4/9 display on screen. #40
@juj

This comment has been minimized.

Copy link
Owner

commented Nov 25, 2018

Thanks for donating the display @Vvvsebastar . Got it now to work, uploaded first working version of code up at a backup branch https://github.com/juj/fbcp-ili9341/tree/kedei_v6_3_mpi3501 - that gets pixels showing on screen, although far from ready.

It looks like according to https://github.com/goodtft/LCD-show the display is a "MPI3501" controller. That is a new one, have not encountered this before. The implementation was done by by sniffing the data bus from the working binary driver.

Here is a summary of sorts:

  1. Unable to find a datasheet pdf for MPI3501, so poking at the protocol in dark. Protocol commands are partially same as commands in other displays (the industry seems to have copied ad hoc standards/conventions for much of this - 0x2A & 0x2B are pixel rectangle coordinates, 0x2C is pixel submit). Color data is updated in 16bpp, and the command to adjust color mode seems to be similar to other controllers.

  2. The display is a 3-wire display, like was observed above. Initial guess was that it would have been a 1-bit command+16-bits data interleaving framed ILI9486 (which is why the branch implemented it on top of ili9486.cpp), but that is not the case. It is effectively a 24-bits command+8-bits data interleaving framed protocol. As result, the hardware protocol is extremely wasteful, to send over one byte, it needs to be framed in a 32-bit package. This means that -75% of the bandwidth is lost from the framing (in other words, +300% overhead). Pixel data is slightly better, it is actually 16-bit/16-bit command+data framing so only incurs a 50% wastage (or +100% overhead).

  3. Something that took two nights of debugging to figure out, is that there is a peculiar interplay of the touch controller and the LCD display in play. The two pieces are not separate, i.e. it is not possible to just initialize the display, but one must initialize both, they communicate internally somehow. Another head scratcher is that the T_CS and L_CS lines have some kind of interaction as well. After sending each 32-bit frame to the LCD display, one must do a dummy "pump" the Chip Select line of the Touch Controller to be enabled for a fraction of a microsecond (with no actual communication taking place), after which the LCD display CS line needs to be disabled likewise for a ~50ns period. That is, one cannot ignore the T_CS line if touch is not in use, but the LCD display is unable to receive/process commands if the Touch Controller is not flipped after each sent 32-bit frame. This hurts bandwidth and CPU usage, and also prevents use of DMA, because it would mean that the DMA controller should write to three data lines simultaneously in a synchronized manner, instead of just pumping bytes out the SPI MOSI bus, something that the DMA controller on the Pi cannot do (without resorting to bit banging). It is not yet certain if pixel color data writes have the same requirement as well, or if this peculiar LCD+Touch pumping is only needed for initialization and/or bus commands though.

Brief speed testing suggests that the controller can reliably handle a 33.333MHz SPI bus speed, but it was not able to do 40MHz. Because of the CS line juggling, effective bus speed remains lower, about 22mbps (22/33 ~ 67% utilization). Tallying up the above protocol framing with -75% / -50% wastage, the effective pixel bandwidth is something around 5.5mbps - 11mbps. The design choices lose around ~66%-85% of the bandwidth they could have had.

Overall with all the above hindrances accumulated, frame rates in Quake run at around 15 interlaced frames per second (~7.5fps). The hardware design of this MPI3501 is out of this world in comparison with any of the other display controllers out there. I am pondering if I should even bother polishing and merging the above branch in, or just drop it. Even if the redundant CS line pumping turns out to be avoidable for pixel data uploads, the wasteful protocol framing design will hurt performance noticeably.

The only good thing about this MPI3501 may be that it kind of makes ILI9486 look like a Ferrari (and HX8357 a jet airplane).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.