1 2 Previous Next 17 Replies Latest reply: Jan 9, 2015 8:53 AM by dferyance RSS

    TFT screen working under Linux framebuffer driver


      One of the disappointments of the Galileo is its lack of any display hardware. The GPIO is slow which is a problem for driving parallel screens. So my hope on getting it to display anything was through SPI. I found a decent small LCD screen from adafruit (#1651). This was easy enough to get working with their library through the Arduino support. I had to hack the code and put in buffering but it worked. However, to really get something worthwhile it needs to run under a Linux driver.


      It took a long time, but I finally got the screen running in Linux. I was able to compile the FBTFT (notro/fbtft · GitHub) driver with yocto to create an image with it. Through a lot of trial and error, I finally got the driver to work and have xorg running with xterm and xclock. As this is a driver, it should now be possible to do Qt applications -- really anything that can work with the framebuffer or xorg.


      The screen refresh is pretty slow. The scan line is visible on a full refresh. The driver is smart to avoid having to update the entire display if it doesn't have to. Also there are a few tricks I haven't tried yet that may speed it up.


      I only have the display working. I haven't looked into the touchscreen yet. I may have to write my own driver for that.


      I figured I would let the community know that this display will work. If there is interest, I will right up some instructions on how to get it running. I didn't keep a log so it will take some backtracking to write it up.

        • 1. Re: TFT screen working under Linux framebuffer driver

          I would really appreciate a How-To!


          I got the same kind of display last week, but it was announced for the Raspberry Pi. As I realized, that it is driven by SPI, I immediatly was like "must work on Galileo too!" It would be great, if you share your knowledge!

          For german/european readers: Watterott.com has this display for a lower price! See here: RPi-Display - 2.8" Touch-Display für Raspberry Pi (320x240) - Watterott electronic

          • 2. Re: TFT screen working under Linux framebuffer driver

            Guide to using adafruit 2.8 TFT Touch Shield (#1651) with FBTFT as a framebuffer in Linux

            FBTFT supports many different controllers, I expect it will be similar with other displays.


            I used the Intel Galileo BSP version 0.7.5. It might work the latest version but I haven't tried.

            With FBTFT I used commit 5fc26ff3be79745151b2dd59e24f01a7c1d3bc56. This was the latest when I started working on this project.


            Sergey's page detailing the Galileo's GPIOs is indispensable (http://www.malinov.com/Home/sergey-s-blog/intelgalileo-programminggpiofromlinux) Because the shield is designed for Arduino, Adafruit's information about it uses the Arduino pin names. This page contains a mapping from these names to the Gaileo's device names.


                1. Follow Sergey's information on building the Linux image: http://www.malinov.com/Home/sergey-s-blog/intelgalileo-buildinglinuximage

                  Get to the point where you can build image-sdk and run it on the Galileo


                2. Modify image-sdk.bb to add more packages. I used hob to view the list. I added a bunch of xorg ones. Be sure to enable xf86-video-fbdev"


                3. Change to the yocto_build/tmp/work/clanton-poky-linux/linux-yocto-clanton/3.8-r0/linux directory

                  Follow the "README" directions at the bottom of this page: https://github.com/notro/fbtft

                  This is so the kernel build system knows about the new source files.


                4. 4. Modify the fbtft_device.c file. There is a big table of devices. Add a new entry that is the same as the tm022hdh26 with the following changes:

                  max_speed_hz = 25000000

                  gpios should just contain "dc", no other entries.


                  I changed the shield's DC pin. Normally this is IO9 (gpio19). I cut the pin and added a wire to IO2 (gpio14).

                  This is to use the Quark's native gpio instead of the I2C port extender.

                  I didn't notice any speed change but I expect it helped. I used "dc" : 14, however if you don't modify the board, set it to 19.


                  I don't know of any reason FBTFT's custom feature won't work but it didn't work for me. I had to add this new entry.


                5. Run bitbake -c menuconfig virtual/kernel

                  In Device Drivers->Graphics, enable "Support for frame buffer devices"

                  Once on, at the top will be a new entry of "Support for small TFT LCD display modules"

                  Set this new entry to be a module, open it and set all the child entries as modules.


                6. Run bitbake image-sdk again and copy your new image.


                7. While FBTFT can talk to the GPIOs directly, it doesn't know anything about Galileo's multiplexers. These need to be configured for the IO ports to go to the correct headers. Fortunately this can be done in user mode through scripting.

                  I took VintageBit's script he posts here: https://communities.intel.com/message/220452#220452


                  I haven't gotten the CS pin to work yet. This is the next thing for me to work on. This will need to work to be able to use the touch sensor. Until then, I have set this pin to 0 (always enabled). To do this, modify the script. Set gpio42 to 1 and add gpio16 as "out 0 strong".


                  If using IO2 as DC, add gpio31 "out 0 strong" so gpio14 will be directed to IO2.


                  Always run this script before loading fbtft


                8. Finally modprobe fbtft_device name=<entry name from step 4> busnum=1 speed=25000000


                  Check dmesg for any errors. If everything worked ok, you should now have /dev/fb0. Xorg will use that device by default

                  as there are no other video devices on the system.


            As this is doing video with no hardware video support don't expect to play movies, games or anything highly interactive. It is good enough for some basic buttons or other user controls but the refresh rate is slow.


            Here is a picture of it running xclock -- just to show off.



            • 3. Re: TFT screen working under Linux framebuffer driver

              Thank you! I will try it this weekend.


              BTW: Nice case

              • 4. Re: TFT screen working under Linux framebuffer driver

                Thanks for posting. This looks like it will be useful to me.

                • 5. Re: TFT screen working under Linux framebuffer driver


                  I followed the fbtft directions given by dferyance.  I used the adafruit 2.8 but unlike his original post I used BSP 1.0.  But I had a persistent -12 error which I traced to dma_alloc_coherent() call in fbtft-core.c (line824).  The only way I could get past the error was to modprobe fbtft with dma=0.  After that the screen could update.


                  Anyone have any suggestions?


                  Also having trouble getting usb keyboard working...

                  • 6. Re: TFT screen working under Linux framebuffer driver

                    When I was playing with this I tried it with DMA on and it didn't work for me either. The version of FBTFT I used predated a recent check-in that was done that made DMA on the default. So I didn't have to do this because I was using an older version. I never tried troubleshooting the DMA mode so I don't know why it doesn't work. My guess is that since this driver is designed for the raspberry pi it must be doing something that is pi specific.


                    Regarding your keyboard issue, see if you can pinpoint if it is USB / driver issue or if it due to Xorg. Xorg has a few different ways of getting input events. I think when I was doing this, I enabled the kernel event interface and used that for input events. It is also possible you need to enable another Xorg package to support the input method you need. Also run lsusb and see if your device is even detected. I was able to use both a USB mouse and keyboard with the Galileo connected to a hub so it should be possible to get working.

                    • 7. Re: TFT screen working under Linux framebuffer driver

                      I finally got the touchscreen fully working. The tricky part was getting the CS / SS pins to work. The way the Adafruit shield has the pins setup combined with the limited direct-CPU Galileo IO pins required a bunch of remapping -- both in hardware and software.


                      I have attached my touchscreen driver. I have comments in the driver about how to do the CS mapping; it is tricky to describe. I can help out anyone who wants to give this a try. I recommend having some way to look at the CS pins. Having a logic analyzer really helped. The SPI data format just works and doesn't have to be debugged but it is easy to get the mux values or kernel options wrong so the CS or DC pins don't toggle.


                      This driver is a usermode driver that uses uinput. I have been using it with Xorg but it should work with any application that can use the kernel input interface. I wanted to use an interrupt but had to revert to polling. I used up all the CPU-native IO pins and the IO expander doesn't support interrupts (at least as far as I could tell). The polling should be fine with CPU and SPI bus as I added delays and optimized the IO. The amount of delay between loops is adjustable.


                      The driver has two modes, by default it will emulate a touchpad. This means a single tap is a click, a press-and-drag moves the cursor and a tap followed by a press-and-drag will hold and drag. This can be switched off to support only clicking. The touchpad mode is best for working with common desktop applications but the click-only mode is better for working with programs designed for a touchscreen.

                      • 8. Re: TFT screen working under Linux framebuffer driver

                        Hi Daniel,

                        Really appreciate the detailed write-up on the GPIO usage and configuration of SPI devices.  I went with the option to reroute signals IO3->IO9 and IO2->IO8 using a Arduino proto board between Galileo and the Adafruit 2.8,  As you know, the gpio enable script is now somewhat more complex. I attached my latest version of the script in case someone is following our dialog. Eventually I want to build this into a patch for platform init.


                        You mentioned building touch.c on Galileo (instead of in cross-compile toolchain per Intel document).  I was wondering what recipes you needed to add to the full-image recipe list to enable C++ building on the target?  Need to get the C++ runtime into image for linker...


                        • 9. Re: TFT screen working under Linux framebuffer driver

                          The reason I build it on the Galileo is because it was easier for me. I was able to re-build on the board without having to bother with copying the program from the PC over. I expect the cross-compile toolchain should work as well. I am using Sergey's steps on building a LSB compliant image. This image includes GCC and the common libraries.


                          Since you are using a breadboard, I recommend wiring the Galileo IO10 line over to the touchscreen CS pin (IO8). I didn't do this because I am making hardware modifications directly on the shield and it wasn't physically possible. On a breadboard you have a lot more flexibility. The nice thing about this configuration is you don't have to modify the Clanton platform device driver. It defaults to use IO10 for the user-mode SPI support. The fewer driver modifications you need to do the less that could go wrong. When I made this driver change, I wasn't sure which platform driver the board uses (there are several for Clanton -- possibly development variants), so I just changed them all. If you can avoid having to do this, I expect it will be easier.

                          • 10. Re: TFT screen working under Linux framebuffer driver

                            One detail that I will mention in case someone else comes along and reads this set of posts:

                            - the touch program opens the device /dev/spidev1.0, which indicates CS=0, so the fbtft_device driver needs to be loaded with CS=1 on the command line. These parameters are not the actual CS lines, which are instead GPIOs specified using this structure -

                                      static struct pxa2xx_spi_chip cln_ffrd_spi_1_cs_0 = {.gpio_cs = 10};

                            The CS in this case is more of a index into the list of SPI devices attached to the SPI port.  And the SPI driver requires each device to have unique CS.


                            If the Intel silicon had CS lines in the SPI port block then these parameters would correspond to physical lines.

                            Otherwise, the comments in touch.cpp.zip tell the whole story of configuring the  GPIO being used as actual CS.


                            Once you create and install the Cross-compile toolchain (See Chap 7 in BSP Guide), the compile is done by

                                source /opt/clanton-tiny/1.4.2/environment-setup-x86_32-poky-linux

                                ${CXX} -std=c++11 touch.cpp -o touch

                            • 11. Re: TFT screen working under Linux framebuffer driver

                              Good job. Can you throw some light on how to display image using c++ in the display.


                              I have a webcam and I want to display it's output using galileo. Any help is appreciated.

                              • 12. Re: TFT screen working under Linux framebuffer driver

                                That is an odd question, you can display an image however you like. Keep in mind that this is working with in the Linux distribution and not anything specific to the Arduino compatibility layer. So anything running on Linux can use it. You could use one of the common Linux media players or picture viewers. I know for sure that GIMP works but that is more heavyweight than you need. If you want to write your own, either Qt or Gtk+ are good choices for a UI. I have run applications using both toolkits on the Galileo without any problems.


                                Keep in mind the refresh rate is slow due to being over SPI and the Galileo has high latency on SPI calls. Still photos are fine but I wouldn't recommend video. You might even have performance problems on the Quark trying to decode the video.

                                • 13. Re: TFT screen working under Linux framebuffer driver

                                  Hi dferyance,


                                  I am getting following error after running through steps in your post. Can you please help me with this error. Probably the spi master is not active. But I don't know how to debug this.






                                  • 14. Re: TFT screen working under Linux framebuffer driver

                                    From the error message, I suspect your updated fbtft driver didn't get compiled or copied over for some reason. The fbtft source code looks like you can get that error if there is a failure to register the SPI device or the entry in the displays array couldn't be found. If it was a SPI issue, you would also see "failed to register SPI device" in the output. You could try modifying the text of a log message and recompiling. If the output doesn't change, you know something isn't getting built right. I know I was modifying files that were generated by the build process rather than doing things the right way and adding a Yocto layer. So it is possible that you are running into something with the build processing not grabbing the changes you made.


                                    I don't know why I could never get it working, but one alternative you might try is the custom option. The driver supports specifying custom parameters without having to update the display map. Once I found something that worked for me I didn't bother to go back to trying the custom feature but it would simplify setup if we can use that instead of having to make more driver modifications.

                                    1 2 Previous Next