Wiring a Adafruit ILI9341 TFT Display

#1

Hey guys,

I’m trying to wire up a display from Adafruit (ILI9341) using SPI on the mangOH Red (WP7607, Legato 18.10.3). I already managed to add framebuffer support on the software side, which seems to work fine by itself. I can’t seem to get the display itself working though. It just displays a white screen (instead of going black with backlight on as expected), which shows me that the display is not initialized. When doing something like cat /dev/urandom > /dev/fb0 I get random black and white flickers, but no real noisy image as expected, so I suspect that SPI works, but it can’t make sense out of the data.

I load the driver in the following way (which gives me a /dev/fb0):

insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/core/fb_sys_fops.ko
insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/core/syscopyarea.ko
insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/core/sysfillrect.ko
insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/core/sysimgblt.ko
insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/fbtft/fbtft.ko
insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/fbtft/fbtft_device.ko name=adafruit28 busnum=1 gpios=dc:13 debug=7
insmod /lib/modules/3.18.122/kernel/drivers/video/fbdev/fbtft/fb_ili9341.ko

My wiring looks currently like this (I use the IOT#0 card connector):

  • Power (IOT Pin 1, 5V) and GND (IOT Pin 38) is connected to 3-5V and GND on the display.
    Since the display seems to power up fine, this seems to be working.
  • Connect SPI CLK (IOT Pin 16), MISO (17), MOSI (18) and SS (19) to the equally named display pins.
  • I connect the GPIO pin 13 (labeled GPIO_2 / IOT Pin 25 on the IOT card) to the D/C pin of the display. I checked that this pin actually changes its level when changing the value using sysfs.

I should note that the display is mostly used by Raspberry users and was probably developed for it and I can also confirm that it works on a RaPi. I’m currently suspecting that the logic level of 1.8V on the SPI pins is not high enough for the display and thus just displays white. I guess I could use the RaPi connector on the mangOH which have a level of 3.3V? How would I tell the fbtft driver to use that? I only have spi1 in /sys/class/spi_master. Are there any other differences you guys can think of?

Any ideas appreciated.

#2

Some more infos:

Attached a oscilloscope to see what signals are being sent out. I compared them with a raspberry (where the same display is working fine) and noticed that SPI CLK, MISO and MOSI seems to be pretty much the same, except for the level being 1.8V on the mangOH and 3.3V on the Pi.

The difference was the D/C pin (connected to GPIO 13, IOT#0 Pin 25):

The screenshot was taken while doing cat /dev/urandom > /dev/fb0. As you can see, we get a signal, but it is way too low (about 0.6V) to be noticed by the display. On the Pi I see a nice 3.3V level with some dips. The weird thing now is, that I can do the following to see a full 1.8V level:

$ echo 13  > /sys/class/gpio/export
$ echo out > /sys/class/gpio/gpio13/direction
$ echo 1   > /sys/class/gpio/gpio13/value 

With this I get a flat line at 1.8V. So how does it come that the fbtft driver outputs such a low level while sysfs outputs it at a normal level? I also tried different GPIO pins, but although I can access most of them via sysfs I don’t get any signal when I set them as dc pin in the insmod command above.

Please help me out of my confusion. Thanks. :smirk:

#3

I just found out from this answer here that the GPIO situation is a bit more complicated than I thought. GPIO Pin 13 seems to be only named “13” in the sysfs, while the kernel side refers to it as 76.

When I load the driver in the following way, I get a proper 1.8V D/C signal similar to the one from the Pi:

insmod \
   /lib/modules/3.18.122/kernel/drivers/video/fbdev/fbtft/fbtft_device.ko  \
   name=adafruit28 \
   busnum=1 \ 
   gpios=dc:76 \
   debug=5

Display is still not working though (although the flickering increased…). I guess I need to use level shifters to get to 3.3V logic. Or can I somehow use the SPI on the RaPi connector (which is 3.3V) easily from kernel side so fbtft can use it? I found this thread but they seems to use spidev from the userspace side, so probably not usable.

EDIT:

For reference I added the table from drivers/gpio/gpiolib-sysfs.c (3.18.122, legato 18.10.3) here:

static struct ext_gpio_map ext_gpio_wp[]={
        {"1", -1,FUNCTION_UNALLOCATED},
        {"2", 38,FUNCTION_UNALLOCATED},
        {"3", -1,FUNCTION_UNALLOCATED},
        {"4", 30,FUNCTION_UNALLOCATED},
        {"5", -1,FUNCTION_UNALLOCATED},
        {"6", 1022,FUNCTION_UNALLOCATED},
        {"7", 16,FUNCTION_UNALLOCATED},
        {"8", 58,FUNCTION_UNALLOCATED},
        {"9", -1,FUNCTION_UNALLOCATED},
        {"10", -1,FUNCTION_UNALLOCATED},
        {"11", -1,FUNCTION_UNALLOCATED},
        {"12", -1,FUNCTION_UNALLOCATED},
        {"13", 76,FUNCTION_UNALLOCATED},
        {"14", -1,FUNCTION_UNALLOCATED},
        {"15", -1,FUNCTION_UNALLOCATED},
        {"16", -1,FUNCTION_UNALLOCATED},
        {"17", -1,FUNCTION_UNALLOCATED},
        {"18", -1,FUNCTION_UNALLOCATED},
        {"19", -1,FUNCTION_UNALLOCATED},
        {"20", -1,FUNCTION_UNALLOCATED},
        {"21", 8,FUNCTION_UNALLOCATED},
        {"22", 9,FUNCTION_UNALLOCATED},
        {"23", 10,FUNCTION_UNALLOCATED},
        {"24", 11,FUNCTION_UNALLOCATED},
        {"25", 51,FUNCTION_UNALLOCATED},
        {"26", -1,FUNCTION_UNALLOCATED},
        {"27", -1,FUNCTION_UNALLOCATED},
        {"28", 45,FUNCTION_UNALLOCATED},
        {"29", 46,FUNCTION_UNALLOCATED},
        {"30", 47,FUNCTION_UNALLOCATED},
        {"31", 48,FUNCTION_UNALLOCATED},
        {"32", 77,FUNCTION_UNALLOCATED},
        {"33", 78,FUNCTION_UNALLOCATED},
        {"34", -1,FUNCTION_UNALLOCATED},
        {"35", 37,FUNCTION_UNALLOCATED},
#ifdef CONFIG_GPIO_SWIMCU
        {"36", SWIMCU_GPIO_TO_SYS(0),FUNCTION_EMBEDDED_HOST},
        {"37", SWIMCU_GPIO_TO_SYS(1),FUNCTION_EMBEDDED_HOST},
        {"38", SWIMCU_GPIO_TO_SYS(2),FUNCTION_EMBEDDED_HOST},
        {"39", -1,FUNCTION_UNALLOCATED},
        {"40", SWIMCU_GPIO_TO_SYS(3),FUNCTION_EMBEDDED_HOST},
        {"41", SWIMCU_GPIO_TO_SYS(4),FUNCTION_EMBEDDED_HOST},
#else /* CONFIG_GPIO_SWIMCU */
        {"36", -1,FUNCTION_UNALLOCATED},
        {"37", -1,FUNCTION_UNALLOCATED},
        {"38", -1,FUNCTION_UNALLOCATED},
        {"39", -1,FUNCTION_UNALLOCATED},
        {"40", -1,FUNCTION_UNALLOCATED},
        {"41", -1,FUNCTION_UNALLOCATED},
#endif /* !CONFIG_GPIO_SWIMCU */
        {"42", 79,FUNCTION_UNALLOCATED},
        {"43", -1,FUNCTION_UNALLOCATED},
        {"44", -1,FUNCTION_UNALLOCATED},
        {"45", -1,FUNCTION_UNALLOCATED},
        {"46", -1,FUNCTION_UNALLOCATED},
        {"M1", -1,FUNCTION_UNALLOCATED},
        {"M2", -1,FUNCTION_UNALLOCATED},
        {"M3", -1,FUNCTION_UNALLOCATED},
        {"M4", -1,FUNCTION_UNALLOCATED},
        {GPIO_NAME_RI,25,FUNCTION_UNALLOCATED}
};
#4

Hi @c.pahl,

I’m a new member, I’m trying to cross compile the source https://github.com/notro/fbtft for my tft screen, I’m so stuck and don’t know how to do like you. Please! instruct me how to cross compile in wp7607.
Thank you so much.

#5

Hello @Andy,

you’re going to have to compile your own yocto based image in order to get a kernel with framebuffer support (which in turn is capable of loading fbtft). I attached the build instructions I noted down while doing that. You could maybe also get it working via writing .mdef files, as described here, but for the sake of having a consistent build, I recommend to build the driver inside the kernel tree so it gets the same config options as the rest of it.

Here are also some references to help you understand:

yocto.tar.gz (36.2 KB)

#6

Hi @c.pahl,
Thank you so much. It help me a lot :slight_smile: