notro / fbtft

Linux Framebuffer drivers for small TFT LCD display modules. Development has moved to https://git.kernel.org/cgit/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/fbtft?h=staging-testing
1.85k stars 496 forks source link

Sainsmart 1.8" tft spi signal distored / glitching #420

Closed amonbenson closed 7 years ago

amonbenson commented 7 years ago

Hello, I have a problem with my small sainsmart display. After I installed fbtft and rebooted, the display stays white for a short time (as usually), but when the console should come up, one side of the screen turns black with a lot of random placed red green and blue pixels. The other side flickers in diagonally lines as if there was some kind of vertical or horizontal synchronization problem with the spi connection. When I plugged in an HDMI Monitor, I saw the default Raspbian Desktop, and from the colors on the tft screen, it seems to display the right colors, but theres a big problem with the row and column pixel synchronization. I thought it maybe could be that the driver assumes, there is another display with a different resolution plugged in, so it draws one row of pixels over multiple rows on my tft display and that messes up the whole image, but how do I change the driver si that it uses the correct resolution? I hope you can help me with that.

j-schumann commented 7 years ago

Have you tried simply displaying a picture? E.g. like https://github.com/notro/fbtft/wiki/Framebuffer-use#image-viewer, does this work?

I'm having a similar (same?) problem, I can display the image but have some lines with random pixels on the lower border that are not used/blacked out while dmesg correctly displays width&height of the display: graphics fb1: fb_st7735r frame buffer, 128x160, 40 KiB video memory, 4 KiB DMA buffer memory, fps=20, spi0.0 at 32 MHz. When I change the rotation in /etc/modprobe.d/fbtft.conf to portrait the random lines appear at the bottom and the right side (of the image). Also I had to set bgr=1 to correct inverted blue/red color.

stevstrong commented 7 years ago

Try to reduce the SPI frequency down to 24 MHz.

j-schumann commented 7 years ago

Thanks for the reply, was it meant for my problem or for the OP? For me it did not help. I also tried reducing even further to 16Mhz and increased the DMA buffer as the Wiki suggested: graphics fb1: fb_st7735r frame buffer, 160x128, 40 KiB video memory, 16 KiB DMA buffer memory, fps=20, spi0.0 at 16 MHz with no improvement.

stevstrong commented 7 years ago

As alternative, to make sure that the display is OK, if you have an Arduino, you could try the Adafruit library.

amonbenson commented 7 years ago

Ok, so the thing with the SPI frequency did it. It's now working propably, I only wonder why the "sainsmart18" setting didn't work and I had to change the settings manualy.

Thanks for your replies.

stevstrong commented 7 years ago

@j-schumann The boards contain ICs from different stocks, so it is usual that they can behave differently. At higher frequencies is always getting critical. I would try to lower even more the SPI clock to exclude all other failure reasons.

j-schumann commented 7 years ago

@stevstrong Thanks for your help. Turns out the problem is the rotation setting. WIth no rotation at all (portrait, 128x160) the display works fine. The problem could probably be handled within the set_addr_win() in fb_st7735r.c (https://github.com/notro/fbtft/blob/master/fb_st7735r.c#L97) which should use different offsets for different rotation values.

notro commented 7 years ago

With regards to speed: Most controller datasheets states 10MHz as max speed. But experience shows that this can be pushed quite a lot.

fb_st7735r has a set_var() function that can be a problem for those that use a custom init= sequence. flexfb or another driver that doesn't have set_var() and uses MIPI_DCS_SET_ADDRESS_MODE in set_addr_win() can be used. Many drivers are MIPI compliant and can be used interchangeably.

When I first wrote fbtft I had 2 displays and knew nothing about the MIPI standard and that the only thing specific to controllers,in this context, are the interface and which registers to set for a framebuffer transfer. set_var() and init_display() should never have been in the controller driver. But here we are.