When you want to connect a display to the Intel Edison module, you should utilise the existing Linux infrastructure and use a kernel framebuffer driver instead of writing your own screen functions based on Arduino libraries.
At the time of writing the article, the Linux kernel SPI support was broken in the original Intel kernel. So, I used Primiano’s kernel that fixed the SPI support. It works perfectly for me, it may not contain the latest Intel’s modifications. Use it on your own risk.
First, I downloaded the Intel sources from http://iotdk.intel.com/src/3.0/edison/. I extracted them into ~/edison in my home directory and followed the instructions for compiling it.
Then I replaced the kernel in ~/edison/poky/linux-kernel by my own, but I kept the directories .git and .meta intact.
I increased the revision number in the variable PR = “r3″ in the file ~/edison/poky/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/linux-externalsrc.bb
I added my new configuration parameters for fbtft into the file ~/edison/poky/linux-kernel/arch/x86/configs/i386_edison_defconfig
I downloaded the fbtft sources. I created the folder ~/edison/poky/linux-kernel/drivers/video/fbtft and extracted the fbtft sources into the folder.
I added the line in ~/edison/poky/linux-kernel/drivers/video/Kconfig before the line “endmenu”.
source "drivers/video/fbtft/Kconfig"
I added the line in ~/edison/poky/linux-kernel/drivers/video/Makefile
obj-$(CONFIG_FB_TFT) += fbtft/
Then I edited the file ~/edison/poky/linux-kernel/drivers/video/fbtft/fbtft_device.c
I added the header
#include <linux/spi/intel_mid_ssp_spi.h>
Then I added the description of my display into the list of displays.
Where “reset” uses the number 49 of the GP49 pin, “dc” is GP15.
The pin “led” is GP14 and I use it in my custom initialization code in the file fb_ssd1322.c
It seems that the chip SSD1322 supports speeds only up to 12.5MHz, but the Edison must be able to support speeds up to 25MHz.
I added the lines to the file ~/edison/poky/meta-intel-edison/meta-intel-edison-bsp/conf/machine/edison.conf to autoload the fbtft module.
Where busnum=5 is the SPI bus number on the Edison.,
name=er_oled028 defines my oled display from fbtft_device.c,
debug=7 shows more debugging information. It’s optional.
Then I recompiled the kernel and flashed my Edison.
I compiled mplayer on the Edison and played a sample video. I couldn’t find a video with the same dimensions as my display, but it should work in the full-screen mode too.
The Intel Edison doesn’t have a video interface; so, you connect an OLED or TFT LCD display via the SPI interface using the Linux kernel video module framebuffer.
After reading the documentation for the display, I connected it to the Edison via the 4-wire SPI interface, which requires an additional GPIO pin for the D/C signal (Write Data/Write Command). The 3-wire SPI interface uses the 9 bit SPI interface and should be avoided.
I compared the timing diagrams for the SSD1322 chip with the SPI Transfer Modes and found that it uses the SPI Mode 3.
Schematic
Here is the schematic of my SSD1322 shield for the Intel Edison.
Connections between the Edison and the Display:
GP49 -> RES(Reset Signal Input)
GP15 -> D/C(Data/Command Control)
GP110_SPI_2_FS0(CS0) -> CS(Chip Select Input)
GP109_SPI_2_CLK -> D0/SCLK(Serial Clock)
GP115_SPI_2_TXD -> D1/SDIN(Serial Data Input)
I also connected GP14 to the SHDN pin of the +12V voltage regulator.
fbtft download and configuration
The latest code from the notro/fbtft repository didn’t work for me.
I used the older code presslab-us/fbtft, which also included support for my chip SSD1322.
After I compiled the Edison image for the first time, I copied these two hidden directories into another folder (I placed the Edison sources into the “edison” directory in my home directory); so, I can return the sources to the original state by copying these hidden directories back at any moment.
I added the line in ~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/drivers/video/Kconfig before the line “endmenu”.
source "drivers/video/fbtft/Kconfig"
I added the line in ~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/drivers/video/Makefile
obj-$(CONFIG_FB_TFT) += fbtft/
Then I edited the file ~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/drivers/video/fbtft/fbtft_device.c
I added the header
#include <linux/spi/intel_mid_ssp_spi.h>
Then I added the description of my display into the list of displays.
Where “reset” uses the number 49 of the GP49 pin, “dc” is GP15.
The pin “led” is GP14 and I use it in my custom initialization code in the file fb_ssd1322.c
DMA has to be disabled because the DMA code in intel_mid_ssp_spi.h is broken.
If you enable it, you can see errors like this: “intel_mid_ssp_spi_unified 0000:00:07.1: ERROR : DMA buffers already mapped”
I created the kernel configuration file fbtft.cfg in the same directory “recipes-kernel/linux/files/”:
CONFIG_FRAMEBUFFER_CONSOLE=m
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=m
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_BACKLIGHT=y
CONFIG_FB_TFT=m
# CONFIG_FB_TFT_GU39XX is not set
# CONFIG_FB_TFT_HX8340BN is not set
# CONFIG_FB_TFT_HX8347D is not set
# CONFIG_FB_TFT_ILI9320 is not set
# CONFIG_FB_TFT_ILI9325 is not set
# CONFIG_FB_TFT_ILI9341 is not set
# CONFIG_FB_TFT_PCD8544 is not set
# CONFIG_FB_TFT_SSD1289 is not set
# CONFIG_FB_TFT_SSD1351 is not set
CONFIG_FB_TFT_SSD1322=m
# CONFIG_FB_TFT_ST7735R is not set
# CONFIG_FB_FLEX is not set
CONFIG_FB_TFT_FBTFT_DEVICE=m
# CONFIG_TOUCHSCREEN_ADS7846_DEVICE is not set
I commented the line in the file board.c for the device ads7955 that occupies the same SPI busnum=5, cs=0 that we use for the display.
Then I ran the same git sequence to generate the patch file “platform_ssd1322.patch” and copied it into the same “recipes-kernel/linux/files” directory.
When all patch and configuration files were ready, I added links to them into the file “~/edison/edison-src/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/linux-yocto_3.10.bbappend”.
The Intel Edison board is shipped with the Yocto Linux distribution installed. Yocto allows an experienced developer to compile a small-size Linux image with only the selected packages. Then the image is flashed into the board. It’s not as convenient as Ubuntu as there are no pre-compiled packages that are easy to install.
I wanted to add the program mc (Midnight Commander); so, I had to recompile the Yocto image. My computer OS is Linux Ubuntu 14.04. I experienced a few problems while compiling; so, I’ll describe them here.
Downloaded the package Linux source files from the Intel Edison Software Downloads page. At the time of writing, it was in the section Intel Edison® Board Firmware Software Release 2.1.
I install everything related to the Intel Edison into the directory /home/farit/edison. The Linux sources consume 11G in that directory.
Decompressed the source package:
tar xzf edison-src-ww25.5-15.tgz -C /home/farit/edison/
cd /home/farit/edison/edison-src/
Moved my download and build cache (also called sstate) directories from the default location under the build directory, using the –dl_dir and –sstate_dir options. To create download and sstate directory, used the mkdir command:
After the setup, I ran these commands recommended by the setup script:
cd /home/farit/edison/edison-src
source poky/oe-init-build-env
bitbake edison-image
The compilation took 5 or so hours. I should’ve used the SSD disk. But most files have been downloaded and cached now; so, it doesn’t take much time the second time.
Then I decided to compile in Midnight Commander. I checked the name of the package on the Yocto recipes directory. It was “mc”.
I opened the file /home/farit/edison/edison-src/meta-intel-edison/meta-intel-edison-distro/recipes-core/images/edison-image.bb and added the lines at the bottom:
#Midnight Commander
IMAGE_INSTALL += "mc"
Then ran again:
cd /home/farit/edison/edison-src
source poky/oe-init-build-env
bitbake edison-image
At first, the command complained about the non-existing mkimage program, which is in the package u-boot-tools:
Error : ota_update.scr creation failed, mkimage tool not found
I added a symlink to mkimage and ran the postBuild.sh script again:
cd /home/farit/edison/edison-src
mkdir -p u-boot/tools
cd u-boot/tools
ln -s /usr/bin/mkimage mkimage
When there were no errors, I looked in the directory /home/farit/edison/edison-src/build/toFlash. It contained the same files as in the Intel’s firmware image.
I ran the command flashall.sh in it as root. I added myself into the group “dialout”; so, I should be able to connect to a USB port as a regular user. I’ll check it again the next time.
By default, the subshell (Ctrl-O) doesn’t work in Midnight Commander as it requires bash. Change your user shell from the default “/bin/sh” to “/bin/bash” in /etc/passwd.
When I want to quickly recompile just the kernel after changes, I run these commands:
cd /home/farit/edison/edison-src
source poky/oe-init-build-env
bitbake -f linux-yocto
I connected my programmer AVRISP mkII to the ISP header of the board to upload the Arduino bootloader. I also connected the FTDI device to provide the 5V power to the board; otherwise, programming doesn’t work.
I use the variant of the microcontroller pin definitions “avr_developers”, also known as “sanguino” for my project.
You can find the definitions in the file ~/arduino/hardware/arduino/avr/variants/avr_developers/pins_arduino.h
I use my AVRISP mkII programmer to load the bootloader into the microcontroller. I use Atmel AVR Studio (version is 4.19).
I go to Tools -> Program AVR -> Connect. Then I select my programmer.
Then I copy the files from the downloaded archive into the hardware/arduino/avr/ subdirectory of the installed Arduino directory and add the settings for the avr_developers board into boards.txt.