<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hobby &#187; intel edison</title>
	<atom:link href="https://hobby.farit.ru/tag/intel-edison/feed/" rel="self" type="application/rss+xml" />
	<link>https://hobby.farit.ru</link>
	<description></description>
	<lastBuildDate>Fri, 27 Feb 2026 07:17:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.39</generator>
	<item>
		<title>Qt5 GUI on Intel Edison</title>
		<link>https://hobby.farit.ru/qt5-gui-intel-edison/</link>
		<comments>https://hobby.farit.ru/qt5-gui-intel-edison/#comments</comments>
		<pubDate>Mon, 06 Jun 2016 06:27:46 +0000</pubDate>
		<dc:creator><![CDATA[Farit]]></dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[intel edison]]></category>

		<guid isPermaLink="false">http://hobby.farit.ru/?p=159</guid>
		<description><![CDATA[If you want to create a graphical user interface (GUI) for the Intel Edison, it&#8217;s better to use the popular Qt cross-platform framework. Then you will be able to develop and debug a program on your powerful desktop computer and then deploy it to your Edison and test it there. My hardware and Linux kernel [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>If you want to create a graphical user interface (GUI) for the Intel Edison, it&#8217;s better to use the popular <a href="https://www.qt.io/" target="_blank">Qt cross-platform framework</a>.<br />
Then you will be able to develop and debug a program on your powerful desktop computer and then deploy it to your Edison and test it there.</p>
<h5>My hardware and Linux kernel configuration</h5>
<p>I used my shield that has a SSD1322 based display connected to the SPI bus and 4 push buttons connected to GPIOs.<br />
The display is controlled through <a href="http://hobby.farit.ru/linux-framebuffer-fbtft-with-dma-for-intel-edison/" target="_blank">the Linux framebuffer kernel module fbtft</a>.<br />
The buttons are controlled through <a href="http://hobby.farit.ru/connecting-buttons-intel-edison/" target="_blank">the gpio-keys module</a>.</p>
<h5>QT5 Yocto Client package installation</h5>
<p>My Edison source packages are located in the folder ~/edison.</p>
<p>I increased the size of my root Edison partition in the file ~/edison/poky/meta-intel-edison/meta-intel-edison-distro/recipes-core/images/edison-image.bb</p>
<pre class="brush: plain; title: ; notranslate">
IMAGE_ROOTFS_SIZE = &quot;1048576&quot;
</pre>
<p>I downloaded a new meta package meta-qt5.<br />
At the time of writing, the Intel Edison packages used the openembedded branch called &#8220;dizzy&#8221;.</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/edison/poky
git clone -b dizzy https://github.com/meta-qt5/meta-qt5.git
</pre>
<p>I modified the configuration file ~/edison/build_edison/conf/auto.conf<br />
I added some Qt packages and enabled some configuration options. I may select something else in the future.</p>
<p>The Intel Edison has no GPU. So, the Qt OpenGL based modules don&#8217;t work. Among them are Qt Quick and Qt Declarative and the packages that depend on these two.</p>
<pre class="brush: cpp; title: ; notranslate">
DISTRO = &quot;poky-edison&quot;
MACHINE = &quot;edison&quot;
DISTRO_FEATURES_append = &quot; alsa bluetooth x11&quot;
PACKAGE_CLASSES = &quot;package_ipk&quot;
BB_DANGLINGAPPENDS_WARNONLY = &quot;1&quot;
EDISONREPO_TOP_DIR = &quot;${TOPDIR}/../poky&quot;

IMAGE_INSTALL_append = &quot; tinyb&quot;
IMAGE_INSTALL_append = &quot; tinyb-dev&quot;
#IMAGE_INSTALL_append = &quot; openzwave&quot;
IMAGE_INSTALL_append = &quot; bacnet-stack&quot;
IMAGE_INSTALL_append = &quot; libmodbus&quot;
IMAGE_INSTALL_append = &quot; mc&quot;
IMAGE_INSTALL_append = &quot; qtbase qtbase-fonts \
    qtbase-plugins \
    qtbase-tools \
    qtimageformats-plugins&quot;
IMAGE_INSTALL_append_core2-32 = &quot; libft4222&quot;
IMAGE_INSTALL_append_edison = &quot; libft4222&quot;
LICENSE_FLAGS_WHITELIST_append = &quot; ftdi&quot;
GCCVERSION = &quot;4.9%&quot;

PACKAGECONFIG_DISTRO_append_pn-qtbase = &quot; linuxfb icu alsa pulseaudio sql-sqlite&quot;
</pre>
<p>I modified the file ~/edison/build_edison/conf/bblayers.conf and added the meta-qt5 layer at the end of BBLAYERS.</p>
<pre class="brush: cpp; title: ; notranslate"> 
LCONF_VERSION = &quot;6&quot;

BBPATH = &quot;${TOPDIR}&quot;
BBFILES ?= &quot;&quot;

BBLAYERS ?= &quot; \
  ${TOPDIR}/../poky/meta \
  ${TOPDIR}/../poky/meta-intel-edison/meta-intel-arduino \
  ${TOPDIR}/../poky/meta-intel-edison/meta-intel-edison-bsp \
  ${TOPDIR}/../poky/meta-intel-edison/meta-intel-edison-distro \
  ${TOPDIR}/../poky/meta-intel-iot-devkit \
  ${TOPDIR}/../poky/meta-intel-iot-middleware \
  ${TOPDIR}/../poky/meta-java \
  ${TOPDIR}/../poky/meta-oic \
  ${TOPDIR}/../poky/meta-openembedded/meta-filesystems \
  ${TOPDIR}/../poky/meta-openembedded/meta-networking \
  ${TOPDIR}/../poky/meta-openembedded/meta-oe \
  ${TOPDIR}/../poky/meta-openembedded/meta-python \
  ${TOPDIR}/../poky/meta-openembedded/meta-ruby \
  ${TOPDIR}/../poky/meta-openembedded/meta-webserver \
  ${TOPDIR}/../poky/meta-yocto \
  ${TOPDIR}/../poky/meta-yocto-bsp \
  ${TOPDIR}/../poky/meta-qt5 \
  &quot;
BBLAYERS_NON_REMOVABLE ?= &quot; \
  ${TOPDIR}/../poky/meta \
  ${TOPDIR}/../poky/meta-yocto \
  &quot;
</pre>
<p>Then the usual Edison image compilation stage.<br />
You must insert yourself into the group &#8220;dialout&#8221; on Linux Ubuntu to have permissions to run the script &#8220;flashall.sh&#8221;.</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/edison/poky/
source oe-init-build-env ../build_edison/
bitbake edison-image u-boot
../poky/meta-intel-edison/utils/flash/postBuild.sh .
./toFlash/flashall.sh
</pre>
<h5>Qt5 Host cross-platform SDK compilation</h5>
<p>I modified the file ~/edison/poky/meta-qt5/recipes-qt/packagegroups/packagegroup-qt5-toolchain-target.bb<br />
and deleted all packages from the list RDEPENDS_${PN} that depend on Qt Quick and Qt Declarative. My list may change in the future.</p>
<pre class="brush: cpp; title: ; notranslate">
RDEPENDS_${PN} += &quot; \
    packagegroup-core-standalone-sdk-target \
    libsqlite3-dev \
    qtbase-dev \
    qtbase-fonts \
    qtbase-mkspecs \
    qtbase-plugins \
    qtbase-staticdev \
    qtconnectivity-dev \
    qtconnectivity-mkspecs \
    qtimageformats-dev \
    qtimageformats-plugins \
    qtserialport-dev \
    qtserialport-mkspecs \
    qtsvg-dev \
    qtsvg-mkspecs \
    qtsvg-plugins \
    qtsystems-dev \
    qtsystems-mkspecs \
    qttools-dev \
    qttools-mkspecs \
    qttools-staticdev \
    qttools-tools \
    qtxmlpatterns-dev \
    qtxmlpatterns-mkspecs \
&quot;
</pre>
<p>I compiled the SDK.</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/edison/poky/
source oe-init-build-env ../build_edison/
bitbake meta-toolchain-qt5
</pre>
<p>I ran the new SDK installer in ~/edison/build_edison/tmp/deploy/sdk</p>
<pre class="brush: bash; title: ; notranslate">
sh poky-edison-glibc-x86_64-meta-toolchain-qt5-core2-32-toolchain-1.7.3.sh
</pre>
<p>It installed the SDK into the default folder /opt/poky-edison/1.7.3<br />
I opened the directory /opt/poky-edison/1.7.3/sysroots/x86_64-pokysdk-linux/usr/bin/i586-poky-linux<br />
and created symlinks. Without them, my system compiler and linker in /usr/bin are called instead.</p>
<pre class="brush: bash; title: ; notranslate">
ln -s i586-poky-linux-g++ g++
ln -s i586-poky-linux-cpp cpp
ln -s i586-poky-linux-ld ld
ln -s i586-poky-linux-gdb gdb
</pre>
<h5>Qt Creator IDE installation</h5>
<p>I installed Qt Creator from <a href="https://download.qt.io/archive/qt/5.3/5.3.2/" target="_blank">https://download.qt.io/archive/qt/5.3/5.3.2/</a>, as the version of Qt in the Yocto package is 5.3.2.<br />
But, probably, the one from the Linux distribution should work as well.<br />
I installed it in the directory ~/Qt.</p>
<p>I modified the script ~/Qt/Tools/QtCreator/bin/qtcreator.sh, so it will load the environment variables for the SDK. I put the new line at the very top of the script.</p>
<pre class="brush: bash; title: ; notranslate">
source /opt/poky-edison/1.7.3/environment-setup-core2-32-poky-linux
#! /bin/sh
</pre>
<p>On my Edison I created the user &#8220;farit&#8221; and added him to the group &#8220;video&#8221; that has permissions to write to the framebuffer and read input buttons. His home directory on the Edison is &#8220;/home/farit&#8221;.</p>
<pre class="brush: bash; title: ; notranslate">
usermod -a -G video farit
</pre>
<p>I modified the menu link on my desktop to run the script ~/Qt/Tools/QtCreator/bin/qtcreator.sh to open Qt Creator.</p>
<p>In Qt Creator, I opened the menu Tools -> Options -> Devices and added my Edison device as &#8220;Generic Linux Device&#8221;.<br />
I named it &#8220;edison&#8221; and provided the name and password combination for the user &#8220;farit&#8221;. Then tested the connection.</p>
<p>I opened the menu Tools > Options > Build &#038; Run.<br />
I opened the tab &#8220;Qt Versions&#8221;, clicked on the button &#8220;Add&#8221; and browsed to select qmake</p>
<pre class="brush: plain; title: ; notranslate">
/opt/poky-edison/1.7.3/sysroots/x86_64-pokysdk-linux/usr/bin/qt5/qmake
</pre>
<p>I opened the tab &#8220;Compilers&#8221;, clicked on the button &#8220;Add&#8221;, selected &#8220;GCC&#8221; and browsed to select gcc</p>
<pre class="brush: plain; title: ; notranslate">
/opt/poky-edison/1.7.3/sysroots/x86_64-pokysdk-linux/usr/bin/i586-poky-linux/i586-poky-linux-gcc
</pre>
<p>I opened the tab &#8220;Debuggers&#8221;, clicked on the button &#8220;Add&#8221; and browsed to select gdb. I named it GDB.</p>
<pre class="brush: plain; title: ; notranslate">
/opt/poky-edison/1.7.3/sysroots/x86_64-pokysdk-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb
</pre>
<p>I opened the tab &#8220;Kits&#8221;, clicked on the button &#8220;Add&#8221; and filled in the form.<br />
I selected the values for Qt, Compiler, Debugger that I just defined in the previous steps.</p>
<p>Name: edison<br />
Device type: Generic Linux Device<br />
Device: edison<br />
Sysroot: /opt/poky-edison/1.7.3/sysroots/x86_64-pokysdk-linux<br />
Compiler: GCC<br />
Debugger: GDB<br />
Qt Version: Qt 5.3.2</p>
<h5>Sample Qt program</h5>
<p>I clicked on &#8220;New Project&#8221; and selected Applications -> Qt Widgets Application.<br />
I named it &#8220;testik&#8221;.</p>
<p>In testik.pro, I added the path &#8220;/home/farit&#8221;, where Qt Creator will copy the executable on the Edison.</p>
<pre class="brush: cpp; title: ; notranslate">
#-------------------------------------------------
#
# Project created by QtCreator 2016-06-02T14:32:35
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = testik
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

target.path = /home/farit
INSTALLS += target
</pre>
<p>In mainwindow.h, I only added the prototype for the function &#8220;keyPressEvent&#8221;.</p>
<pre class="brush: cpp; title: ; notranslate">
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include &lt;QMainWindow&gt;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    void keyPressEvent(QKeyEvent *);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
</pre>
<p>main.cpp is the default one</p>
<pre class="brush: cpp; title: ; notranslate">
#include &quot;mainwindow.h&quot;
#include &lt;QApplication&gt;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
</pre>
<p>In mainwindow.cpp, I implemented the function &#8220;keyPressEvent&#8221;.</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;QKeyEvent&gt;
#include &lt;QDebug&gt;
#include &quot;mainwindow.h&quot;
#include &quot;ui_mainwindow.h&quot;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui-&gt;setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event-&gt;key() == Qt::Key_Up)
    {
        if (event-&gt;isAutoRepeat()) {
             ui-&gt;myLabel-&gt;setText(&quot;You auto pressed Up&quot;);
        }
        else {
            ui-&gt;myLabel-&gt;setText(&quot;You pressed Up&quot;);
        }
    }
    else if(event-&gt;key() == Qt::Key_Down)
    {
        ui-&gt;myLabel-&gt;setText(&quot;You pressed Down&quot;);
    }
}
</pre>
<p>In mainwindow.ui, I created a label &#8220;myLabel&#8221;.<br />
In the MainWindow properties, I clicked on the &#8220;palette&#8221; button and made the background transparent by setting the opacity to 0 for &#8220;Window&#8221;. I changed &#8220;WindowText&#8221; to white by selecting the color #FFFFFF.</p>
<p>In the &#8220;Projects&#8221; tab in the &#8220;Run&#8221; section, I added the arguments for the executable, so it can write to the default framebuffer /dev/fb0 and read input from /dev/input/event0.</p>
<pre class="brush: plain; title: ; notranslate">
-platform linuxfb -plugin EvdevKeyboard
</pre>
<figure id="attachment_163" style="width: 834px;" class="wp-caption aligncenter"><a href="http://hobby.farit.ru/wp-content/uploads/2016/06/qt_test.png"><img src="http://hobby.farit.ru/wp-content/uploads/2016/06/qt_test-834x854.png" alt="Qt test program running" width="834" height="854" class="size-medium wp-image-163" /></a><figcaption class="wp-caption-text">Qt test program running</figcaption></figure>
]]></content:encoded>
			<wfw:commentRss>https://hobby.farit.ru/qt5-gui-intel-edison/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connecting Buttons to Intel Edison</title>
		<link>https://hobby.farit.ru/connecting-buttons-intel-edison/</link>
		<comments>https://hobby.farit.ru/connecting-buttons-intel-edison/#comments</comments>
		<pubDate>Sun, 05 Jun 2016 06:29:55 +0000</pubDate>
		<dc:creator><![CDATA[Farit]]></dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[intel edison]]></category>

		<guid isPermaLink="false">http://hobby.farit.ru/?p=152</guid>
		<description><![CDATA[The Intel Edison has multiple GPIO pins, which can be connected to push buttons. I use the gpio-keys Linux driver. Each button emits an event, which can be read in the same way as a keyboard event. Schematic Here is the schematic of my shield with the push buttons. The buttons are SW2, SW3, SW4, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>The Intel Edison has multiple GPIO pins, which can be connected to push buttons.</p>
<p>I use the gpio-keys Linux driver. Each button emits an event, which can be read in the same way as a keyboard event.</p>
<h5>Schematic</h5>
<p>Here is the schematic of my shield with the push buttons. The buttons are SW2, SW3, SW4, SW5.<br />
<figure id="attachment_104" style="width: 854px;" class="wp-caption aligncenter"><a href="http://hobby.farit.ru/wp-content/uploads/2016/04/display_schematic.png"><img class="size-medium wp-image-104" src="http://hobby.farit.ru/wp-content/uploads/2016/04/display_schematic-854x604.png" alt="Shiled with push buttons for Intel Edison" width="854" height="604" /></a><figcaption class="wp-caption-text">Shield with Push Buttons for Intel Edison</figcaption></figure></p>
<h5>GPIO pullup code</h5>
<p>As you can see, one side of a button is connected to the ground and another to a GPIO pin. I could use external pullup resistors, but the Intel Edison has built-in pullup resistors, which I activated instead. The current kernel code doesn&#8217;t have a function for setting a pullup resitor, so I had to write my own.</p>
<p>I added the function lnw_gpio_set_pull_alt into the Linux kernel file drivers/gpio/gpio-langwell.c</p>
<pre class="brush: cpp; title: ; notranslate">
void lnw_gpio_set_pull_alt(unsigned gpio, int value, int pullup_value)
{
	struct lnw_gpio *lnw;
	u32 flis_offset;
	u32 flis_value;
	unsigned long flags;

	/* use this trick to get memio */
	lnw = irq_get_chip_data(gpio_to_irq(gpio));
	if (!lnw) {
		pr_err(&quot;langwell_gpio: can not find pin %d\n&quot;, gpio);
		return;
	}
	if (gpio &lt; lnw-&gt;chip.base || gpio &gt;= lnw-&gt;chip.base + lnw-&gt;chip.ngpio) {
		dev_err(lnw-&gt;chip.dev, &quot;langwell_gpio: wrong pin %d to config alt\n&quot;, gpio);
		return;
	}
	gpio -= lnw-&gt;chip.base;

	if (lnw-&gt;type != TANGIER_GPIO) {
		return;
    }

	flis_offset = lnw-&gt;get_flis_offset(gpio);
	if (WARN(flis_offset == -EINVAL, &quot;invalid pin %d\n&quot;, gpio))
		return -EINVAL;
	if (is_merr_i2c_flis(flis_offset))
		return;

	spin_lock_irqsave(&amp;lnw-&gt;lock, flags);
	flis_value = get_flis_value(flis_offset);
	if (value) {
		flis_value |= PULLUP_ENABLE;
		flis_value &amp;= ~PULLDOWN_ENABLE;
	} else {
		flis_value |= PULLDOWN_ENABLE;
		flis_value &amp;= ~PULLUP_ENABLE;
	}
	//flis_value |= PUPD_VAL_50K;
    flis_value |= pullup_value;

	set_flis_value(flis_value, flis_offset);
	spin_unlock_irqrestore(&amp;lnw-&gt;lock, flags);
}
EXPORT_SYMBOL_GPL(lnw_gpio_set_pull_alt);
</pre>
<p>Also added its declaration and the constants for the pullup values into the Linux kernel file include/linux/lnw_gpio.h</p>
<pre class="brush: cpp; title: ; notranslate">
#define PUPD_VAL_2K	(0 &lt;&lt; 4)
#define PUPD_VAL_20K	(1 &lt;&lt; 4)
#define PUPD_VAL_50K	(2 &lt;&lt; 4)
#define PUPD_VAL_910	(3 &lt;&lt; 4)
void lnw_gpio_set_pull_alt(unsigned gpio, int value, int pullup_value);
</pre>
<p>I added the definitions for my 4 push buttons into the Linux kernel file arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c<br />
The buttons are for GPIO12, GPIO13, GPIO182, GPIO183.<br />
Each button configured as a general purpose pin by using the multiplexor code: lnw_gpio_set_alt(gb[i].gpio, LNW_GPIO);<br />
The pullup value is set to 50K using the previously written function: lnw_gpio_set_pull_alt(gb[i].gpio, 1, PUPD_VAL_50K);</p>
<pre class="brush: cpp; title: ; notranslate">
/*
 * platform_gpio_keys.c: gpio_keys platform data initilization file
 *
 * (C) Copyright 2008 Intel Corporation
 * Author:
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 */

#include &lt;linux/input.h&gt;
#include &lt;linux/init.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/gpio.h&gt;
#include &lt;linux/gpio_keys.h&gt;
#include &lt;linux/platform_device.h&gt;
#include &lt;asm/intel-mid.h&gt;
#include &quot;platform_gpio_keys.h&quot;
#include &lt;linux/lnw_gpio.h&gt;

/*
 * we will search these buttons in SFI GPIO table (by name)
 * and register them dynamically. Please add all possible
 * buttons here, we will shrink them if no GPIO found.
 */
static struct gpio_keys_button gpio_button[] = {
        {
                .code = KEY_POWER,
                .gpio = -1, /* GPIO number */
                .active_low = 1,
                .desc = &quot;power_btn&quot;,/*Button description*/
                .type = EV_KEY,
                .wakeup = 0,
                .debounce_interval = 3000,
        },
        {
                .code = KEY_UP,
                .gpio = 182,
                .active_low = 1,
                .desc = &quot;up_btn&quot;,
                .type = EV_KEY,
                .wakeup = 0,
                .debounce_interval = 100,
        },
        {
                .code = KEY_DOWN,
                .gpio = 12,
                .active_low = 1,
                .desc = &quot;down_btn&quot;,
                .type = EV_KEY,
                .wakeup = 0,
                .debounce_interval = 100,
        },
        {
                .code = KEY_ESC,
                .gpio = 13,
                .active_low = 1,
                .desc = &quot;back_btn&quot;,
                .type = EV_KEY,
                .wakeup = 0,
                .debounce_interval = 100,
        },
        {
                .code = KEY_ENTER,
                .gpio = 183,
                .active_low = 1,
                .desc = &quot;down_btn&quot;,
                .type = EV_KEY,
                .wakeup = 0,
                .debounce_interval = 100,
        },
};

static struct gpio_keys_platform_data gpio_keys = {
	.buttons	= gpio_button,
	.rep		= 1,
	.nbuttons	= -1, /* will fill it after search */
};

static struct platform_device pb_device = {
	.name		= DEVICE_NAME,
	.id		= -1,
	.dev		= {
		.platform_data	= &amp;gpio_keys,
	},
};

/*
 * Shrink the non-existent buttons, register the gpio button
 * device if there is some
 */
static int __init pb_keys_init(void)
{
	struct gpio_keys_button *gb = gpio_button;
	int i, num, good = 0;

	num = sizeof(gpio_button) / sizeof(struct gpio_keys_button);
	for (i = 0; i &lt; num; i++) {
		pr_info(&quot;info[%2d]: name = %s, gpio = %d\n&quot;,
			 i, gb[i].desc, gb[i].gpio);
		if (gb[i].gpio == -1)
			continue;

                if (gb[i].gpio &gt; 0) {
                    lnw_gpio_set_alt(gb[i].gpio, LNW_GPIO);
                    lnw_gpio_set_pull_alt(gb[i].gpio, 1, PUPD_VAL_50K);
                }

		if (i != good)
			gb[good] = gb[i];
		good++;
	}

	if (good) {
		gpio_keys.nbuttons = good;
		return platform_device_register(&amp;pb_device);
	}
	return 0;
}
late_initcall(pb_keys_init);
</pre>
<h5>Testing Buttons</h5>
<p>When the new Linux kernel was recompiled and flashed to the Intel Edison, I could verify the buttons.</p>
<p>I checked the files in the directory for the GPIO12: /sys/kernel/debug/gpio_debug/gpio12<br />
current_pinmux was mode0<br />
current_pullmode was pullup<br />
current_pullstrength was 50k</p>
<p>I ran the command and tried to push on the buttons. I received some symbols. It meant that the buttons worked.</p>
<pre class="brush: bash; title: ; notranslate">
cat /dev/input/event0
</pre>
<p>I copied the file evtest.c from <a href="http://elinux.org/images/9/93/Evtest.c" target="_blank">http://elinux.org/images/9/93/Evtest.c</a> and compiled it on my Edison.</p>
<pre class="brush: bash; title: ; notranslate">
gcc evtest.c -o evtest
</pre>
<p>I ran the program evtest and got expected results.</p>
<pre class="brush: bash; title: ; notranslate">
# ./evtest /dev/input/event0
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: &quot;gpio-keys&quot;
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 1 (Esc)
    Event code 28 (Enter)
    Event code 103 (Up)
    Event code 108 (Down)
  Event type 20 (Repeat)
Testing ... (interrupt to exit)
Event: time 1465107735.152126, type 1 (Key), code 108 (Down), value 1
Event: time 1465107735.152126, -------------- Report Sync ------------
Event: time 1465107735.344576, type 1 (Key), code 108 (Down), value 0
Event: time 1465107735.344576, -------------- Report Sync ------------
Event: time 1465107743.087594, type 1 (Key), code 103 (Up), value 1
Event: time 1465107743.087594, -------------- Report Sync ------------
Event: time 1465107743.332727, type 1 (Key), code 103 (Up), value 0
Event: time 1465107743.332727, -------------- Report Sync ------------
Event: time 1465107745.988003, type 1 (Key), code 28 (Enter), value 1
Event: time 1465107745.988003, -------------- Report Sync ------------
Event: time 1465107746.187692, type 1 (Key), code 28 (Enter), value 0
Event: time 1465107746.187692, -------------- Report Sync ------------
Event: time 1465107748.336925, type 1 (Key), code 1 (Esc), value 1
Event: time 1465107748.336925, -------------- Report Sync ------------
Event: time 1465107748.552085, type 1 (Key), code 1 (Esc), value 0
Event: time 1465107748.552085, -------------- Report Sync ------------
</pre>
<p>I may change the event key codes for the buttons. I can get the codes from the same file <a href="http://elinux.org/images/9/93/Evtest.c" target="_blank">http://elinux.org/images/9/93/Evtest.c</a></p>
<h5>Accessing /dev/input/event0 as a regular user</h5>
<p>By default, the device /dev/input/event0 is accessible only by root.</p>
<p>I created the file /etc/udev/rules.d/input.rules<br />
I chose the group &#8220;video&#8221; as I will use a user who should be able to access both the video device and the input device.</p>
<pre class="brush: plain; title: ; notranslate">
KERNEL==&quot;event*&quot;, NAME=&quot;input/%k&quot;, MODE=&quot;660&quot;, GROUP=&quot;video&quot;
</pre>
<p>I also created the file with the same contents poky/meta/recipes-core/systemd/systemd/input.rules<br />
and added it into the recipe poky/meta/recipes-core/systemd/systemd_216.bb</p>
<pre class="brush: plain; title: ; notranslate">
SRC_URI = &quot;git://anongit.freedesktop.org/systemd/systemd;branch=master;protocol=git \
           file://binfmt-install.patch \
           file://systemd-pam-configure-check-uclibc.patch \
           file://systemd-pam-fix-execvpe.patch \
           file://systemd-pam-fix-fallocate.patch \
           file://systemd-pam-fix-mkostemp.patch \
           file://optional_secure_getenv.patch \
           file://uclibc-sysinfo_h.patch \
           file://uclibc-get-physmem.patch \
           file://0001-add-support-for-executing-scripts-under-etc-rcS.d.patch \
           file://0001-missing.h-add-fake-__NR_memfd_create-for-MIPS.patch \
           file://0001-Make-root-s-home-directory-configurable.patch \
           file://0001-systemd-user-avoid-using-system-auth.patch \
           file://0001-journal-Fix-navigating-backwards-missing-entries.patch \
           file://0001-tmpfiles-make-resolv.conf-entry-conditional-on-resol.patch \
           file://0001-build-sys-do-not-install-tmpfiles-and-sysusers-files.patch \
           file://0001-build-sys-configure-the-list-of-system-users-files-a.patch \
           file://touchscreen.rules \
           file://input.rules \
           file://00-create-volatile.conf \
           file://init \
           file://run-ptest \
          &quot;
</pre>
]]></content:encoded>
			<wfw:commentRss>https://hobby.farit.ru/connecting-buttons-intel-edison/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Linux Framebuffer fbtft with SPI DMA for Intel Edison</title>
		<link>https://hobby.farit.ru/linux-framebuffer-fbtft-with-dma-for-intel-edison/</link>
		<comments>https://hobby.farit.ru/linux-framebuffer-fbtft-with-dma-for-intel-edison/#comments</comments>
		<pubDate>Tue, 31 May 2016 02:43:50 +0000</pubDate>
		<dc:creator><![CDATA[Farit]]></dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[fbtft]]></category>
		<category><![CDATA[intel edison]]></category>

		<guid isPermaLink="false">http://hobby.farit.ru/?p=140</guid>
		<description><![CDATA[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. The schematics and more technical information about my display and board are in my previous post: Framebuffer fbtft Installation [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>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.</p>
<p>The schematics and more technical information about my display and board are in my previous post: <a href="http://hobby.farit.ru/framebuffer-fbtft-installation-intel-edison-oled-display-ssd1322/" target="_blank">Framebuffer fbtft Installation on Intel Edison for OLED Display SSD1322</a>.</p>
<p>At the time of writing the article, the Linux kernel SPI support was broken in the original Intel kernel. So, I used <a href="https://github.com/primiano/edison-kernel" target="_blank">Primiano&#8217;s kernel</a> that fixed the SPI support. It works perfectly for me, it may not contain the latest Intel&#8217;s modifications. Use it on your own risk.</p>
<p>First, I downloaded the Intel sources from <a href="http://iotdk.intel.com/src/3.0/edison/" target="_blank">http://iotdk.intel.com/src/3.0/edison/</a>. I extracted them into ~/edison in my home directory and followed the instructions for compiling it.</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/edison/poky/
source oe-init-build-env ../build_edison/
bitbake edison-image u-boot
../poky/meta-intel-edison/utils/flash/postBuild.sh .
./toFlash/flashall.sh
</pre>
<p>Then I replaced the kernel in ~/edison/poky/linux-kernel by my own, but I kept the directories .git and .meta intact.<br />
I increased the revision number in the variable PR = &#8220;r3&#8243; in the file ~/edison/poky/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/linux-externalsrc.bb<br />
I added my new configuration parameters for fbtft into the file ~/edison/poky/linux-kernel/arch/x86/configs/i386_edison_defconfig</p>
<p>I downloaded the <a href="https://github.com/notro/fbtft" target="_blank">fbtft sources</a>. I created the folder ~/edison/poky/linux-kernel/drivers/video/fbtft and extracted the fbtft sources into the folder.</p>
<p>I added the line in ~/edison/poky/linux-kernel/drivers/video/Kconfig before the line &#8220;endmenu&#8221;.</p>
<pre class="brush: cpp; title: ; notranslate">
source &quot;drivers/video/fbtft/Kconfig&quot;
</pre>
<p>I added the line in ~/edison/poky/linux-kernel/drivers/video/Makefile</p>
<pre class="brush: cpp; title: ; notranslate">
obj-$(CONFIG_FB_TFT)    += fbtft/
</pre>
<p>Then I edited the file ~/edison/poky/linux-kernel/drivers/video/fbtft/fbtft_device.c</p>
<p>I added the header</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/spi/intel_mid_ssp_spi.h&gt;
</pre>
<p>Then I added the description of my display into the list of displays.<br />
Where &#8220;reset&#8221; uses the number 49 of the GP49 pin, &#8220;dc&#8221; is GP15.<br />
The pin &#8220;led&#8221; is GP14 and I use it in my custom initialization code in the file fb_ssd1322.c</p>
<p>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.</p>
<pre class="brush: cpp; title: ; notranslate">
{
   .name = &quot;er_oled028&quot;,
   .spi = &amp;(struct spi_board_info) {
       .modalias = &quot;fb_ssd1322&quot;,
       .max_speed_hz = 12500000,
       .mode = SPI_MODE_3,
       .bus_num = 5,
       .chip_select = 0,
       .controller_data = &amp;(struct intel_mid_ssp_spi_chip) {
           .burst_size = DFLT_FIFO_BURST_SIZE,
           .timeout = DFLT_TIMEOUT_VAL,
           .dma_enabled = true,
        },
        .platform_data = &amp;(struct fbtft_platform_data) {
           .display = {
               .buswidth = 8,
               .backlight = 0,
               .width = 256,
               .height = 64,
           },
           .gpios = (const struct fbtft_gpio []) {
               { &quot;reset&quot;, 49 },
               { &quot;dc&quot;, 15},
               { &quot;led&quot;, 14},
               {},
           },
       }
   }
},
</pre>
<p>I modified the file ~/edison/poky/linux-kernel/drivers/video/fbtft/fbtft-core.c</p>
<pre class="brush: diff; title: ; notranslate">
--- fbtft-core.c	2015-03-05 02:54:01.000000000 -0800
+++ fbtft-core.c.new	2016-05-30 19:19:21.000000000 -0700
@@ -863,7 +863,7 @@
 	if (txbuflen &gt; 0) {
 		if (dma) {
 			dev-&gt;coherent_dma_mask = ~0;
-			txbuf = dmam_alloc_coherent(dev, txbuflen, &amp;par-&gt;txbuf.dma, GFP_DMA);
+			txbuf = devm_kzalloc(par-&gt;info-&gt;device, txbuflen, GFP_DMA | GFP_ATOMIC);
 		} else {
 			txbuf = devm_kzalloc(par-&gt;info-&gt;device, txbuflen, GFP_KERNEL);
 		}
</pre>
<p>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.<br />
Where busnum=5 is the SPI bus number on the Edison.,<br />
name=er_oled028 defines my oled display from fbtft_device.c,<br />
debug=7 shows more debugging information. It&#8217;s optional.</p>
<pre class="brush: cpp; title: ; notranslate">
KERNEL_MODULE_AUTOLOAD += &quot;fbtft_device&quot;
module_conf_fbtft_device = &quot;options fbtft_device name=er_oled028 busnum=5 debug=7&quot;
KERNEL_MODULE_PROBECONF += &quot;fbtft_device&quot;
</pre>
<p>Then I recompiled the kernel and flashed my Edison.</p>
<p>I compiled mplayer on the Edison and played a sample video. I couldn&#8217;t find a video with the same dimensions as my display, but it should work in the full-screen mode too.</p>
<pre class="brush: bash; title: ; notranslate">
/usr/local/bin/mplayer -vo fbdev ultra.mp4
</pre>
		
		<!-- Begin Video.js Responsive Wrapper -->
		<div style='max-width:854px'>
			<div class='video-wrapper' style='padding-bottom:56.206088992974%;'>
				
	<!-- Begin Video.js -->
	<video id="example_video_id_199922863" class="video-js vjs-default-skin" width="854" height="480" poster="http://hobby.farit.ru/wp-content/uploads/2016/05/video_playing.png" controls preload="none" data-setup='[]'>
		<source src="http://hobby.farit.ru/wp-content/uploads/2016/05/oled_video.mp4" type='video/mp4' />
		
		
	</video>
	<!-- End Video.js -->

			</div>
		</div>
		<!-- End Video.js Responsive Wrapper -->
		
<h5>Downloads</h5>
<p><a href="http://hobby.farit.ru/wp-content/uploads/2016/05/kernel_edison_fbtft.tar.gz">Linux kernel for Edison with SPI DMA fixes and fbtft framebuffer</a></p>
]]></content:encoded>
			<wfw:commentRss>https://hobby.farit.ru/linux-framebuffer-fbtft-with-dma-for-intel-edison/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://hobby.farit.ru/wp-content/uploads/2016/05/oled_video.mp4" length="6725550" type="video/mp4" />
		</item>
		<item>
		<title>Framebuffer fbtft Installation on Intel Edison for OLED Display SSD1322</title>
		<link>https://hobby.farit.ru/framebuffer-fbtft-installation-intel-edison-oled-display-ssd1322/</link>
		<comments>https://hobby.farit.ru/framebuffer-fbtft-installation-intel-edison-oled-display-ssd1322/#comments</comments>
		<pubDate>Mon, 11 Apr 2016 03:59:14 +0000</pubDate>
		<dc:creator><![CDATA[Farit]]></dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[display]]></category>
		<category><![CDATA[fbtft]]></category>
		<category><![CDATA[intel edison]]></category>

		<guid isPermaLink="false">http://hobby.farit.ru/?p=102</guid>
		<description><![CDATA[Update: the version with working SPI DMA The Intel Edison doesn&#8217;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. I used fbtft &#8211; Linux Framebuffer drivers for small TFT LCD display modules by Noralf Tronnes. My display is 2.8&#8243; [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2><span style="color: #ff0000;">Update: <a style="color: #ff0000;" href="http://hobby.farit.ru/linux-framebuffer-fbtft-with-dma-for-intel-edison/">the version with working SPI DMA</a></span></h2>
<p>The Intel Edison doesn&#8217;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.</p>
<p>I used fbtft &#8211; <a href="https://github.com/notro/fbtft" target="_blank">Linux Framebuffer drivers for small TFT LCD display modules</a> by Noralf Tronnes.</p>
<p>My display is <a href="http://www.buydisplay.com/default/2-8-inch-oled-display-256x64-graphic-module-ssd1322-yellow-on-black" target="_blank">2.8&#8243; OLED Display 256&#215;64 Graphic Module SSD1322</a>.</p>
<p>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.</p>
<p>I compared the timing diagrams for the SSD1322 chip with <a href="http://dlnware.com/theory/SPI-Transfer-Modes" target="_blank">the SPI Transfer Modes</a> and found that it uses the SPI Mode 3.</p>
<h5>Schematic</h5>
<p>Here is the schematic of my SSD1322 shield for the Intel Edison.</p>
<figure id="attachment_104" style="width: 854px;" class="wp-caption aligncenter"><a href="http://hobby.farit.ru/wp-content/uploads/2016/04/display_schematic.png"><img class="size-medium wp-image-104" src="http://hobby.farit.ru/wp-content/uploads/2016/04/display_schematic-854x604.png" alt="SSD1322 Shield for Intel Edison" width="854" height="604" /></a><figcaption class="wp-caption-text">The SSD1322 Display Shield for the Intel Edison</figcaption></figure>
<h5>Connections between the Edison and the Display:</h5>
<p>GP49 -&gt; RES(Reset Signal Input)<br />
GP15 -&gt; D/C(Data/Command Control)<br />
GP110_SPI_2_FS0(CS0) -&gt; CS(Chip Select Input)<br />
GP109_SPI_2_CLK -&gt; D0/SCLK(Serial Clock)<br />
GP115_SPI_2_TXD -&gt; D1/SDIN(Serial Data Input)<br />
I also connected GP14 to the SHDN pin of the +12V voltage regulator.</p>
<h5>fbtft download and configuration</h5>
<p>The latest code from the <a href="https://github.com/notro/fbtft" target="_blank">notro/fbtft</a> repository didn&#8217;t work for me.<br />
I used the older code <a href="https://github.com/presslab-us/fbtft" target="_blank">presslab-us/fbtft</a>, which also included support for my chip SSD1322.</p>
<p>I prepared the Edison directory with the Linux sources as described in my article <a href="http://hobby.farit.ru/building-yocto-linux-for-intel-edison/" target="_blank">Building Yocto Linux for Intel Edison</a>.</p>
<p>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 &#8220;edison&#8221; directory in my home directory); so, I can return the sources to the original state by copying these hidden directories back at any moment.</p>
<pre class="brush: plain; title: ; notranslate">
~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/.git
~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/.meta
</pre>
<p>I created the directory &#8220;fbtft&#8221; and copied all fbtft files there.</p>
<pre class="brush: bash; title: ; notranslate">
mkdir ~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/drivers/video/fbtft
</pre>
<p>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 &#8220;endmenu&#8221;.</p>
<pre class="brush: bash; title: ; notranslate">
source &quot;drivers/video/fbtft/Kconfig&quot;
</pre>
<p>I added the line in ~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/drivers/video/Makefile</p>
<pre class="brush: cpp; title: ; notranslate">
obj-$(CONFIG_FB_TFT)    += fbtft/
</pre>
<p>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</p>
<p>I added the header</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;linux/spi/intel_mid_ssp_spi.h&gt;
</pre>
<p>Then I added the description of my display into the list of displays.<br />
Where &#8220;reset&#8221; uses the number 49 of the GP49 pin, &#8220;dc&#8221; is GP15.<br />
The pin &#8220;led&#8221; is GP14 and I use it in my custom initialization code in the file fb_ssd1322.c</p>
<p>DMA has to be disabled because the DMA code in intel_mid_ssp_spi.h is broken.<br />
If you enable it, you can see errors like this: &#8220;intel_mid_ssp_spi_unified 0000:00:07.1: ERROR : DMA buffers already mapped&#8221;</p>
<pre class="brush: cpp; title: ; notranslate">
{
   .name = &quot;er_oled028&quot;,
   .spi = &amp;(struct spi_board_info) {
       .modalias = &quot;fb_ssd1322&quot;,
       .max_speed_hz = 12000000,
       .mode = SPI_MODE_3,
       .bus_num = 5,
       .chip_select = 0,
       .controller_data = &amp;(struct intel_mid_ssp_spi_chip) {
           .burst_size = DFLT_FIFO_BURST_SIZE,
           .timeout = DFLT_TIMEOUT_VAL,
           .dma_enabled = false,
        },
        .platform_data = &amp;(struct fbtft_platform_data) {
           .display = {
               .buswidth = 8,
               .backlight = 0,
               .width = 256,
               .height = 64,
           },
           .gpios = (const struct fbtft_gpio []) {
               { &quot;reset&quot;, 49 },
               { &quot;dc&quot;, 15},
               { &quot;led&quot;, 14},
               {},
           },
       }
   }
},
</pre>
<p>I wrote my custom initialization code for the display ER_OLED028 in fb_ssd1322.c following the documentation for my display.</p>
<pre class="brush: cpp; title: ; notranslate">
static int init_display(struct fbtft_par *par)
{
   fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, &quot;%s()\n&quot;, __func__);

   //reset the chip
   mdelay(5);
   fbtft_par_dbg(DEBUG_RESET, par, &quot;%s()\n&quot;, __func__);
   gpio_set_value(par-&gt;gpio.reset, 0);
   udelay(200);
   gpio_set_value(par-&gt;gpio.reset, 1);
   udelay(200);

   write_reg(par, 0xfd, 0x12); /* Unlock OLED driver IC */
   write_reg(par, 0xae); /* Display Off */
   write_reg(par, 0xb3, 0x91); /* Display divide clockratio/frequency */
   write_reg(par, 0xca, 0x3f); /* Multiplex ratio, 1/64, 64 COMS enabled */
   write_reg(par, 0xa2, 0x00); /* Set offset, the display map starting line is COM0 */
   write_reg(par, 0xa1, 0x00); /* Set start line position */
   write_reg(par, 0xa0, 0x14, 0x11); /* Set remap, horiz address increment, disable colum address remap, */
				                      /*  enable nibble remap, scan from com[N-1] to COM0, disable COM split odd even */
   write_reg(par, 0xb5, 0x00); /* Set GPIO */
   write_reg(par, 0xab, 0x01); /* Select internal VDD */
   write_reg(par, 0xb4, 0xa0, 0xfd); /* Display enhancement A, external VSL, enhanced low GS display quality */
   write_reg(par, 0xc1, 0xff); /* Contrast current, 256 steps, default is 0x7F */
   write_reg(par, 0xc7, 0x0f); /* Master contrast current, 16 steps, default is 0x0F */
   write_reg(par, 0xb1, 0xe2); /* Phase Length */
   write_reg(par, 0xd1, 0x82, 0x20); /* Display enhancement B */
   write_reg(par, 0xbb, 0x1f); /* Pre-charge voltage */
   write_reg(par, 0xb6, 0x08); /* Set Second Pre-Charge Period */
   write_reg(par, 0xbe, 0x07); /* Set VCOMH */
   write_reg(par, 0xa6); /* Normal display */

   //enable VCC
   gpio_set_value(par-&gt;gpio.led[0], 1);
   mdelay(100);
  
   write_reg(par, 0xaf); /* Display ON */

   return 0;
}
</pre>
<p>After all modifications, I created a patch file.<br />
While committing to git, I added the comment line &#8220;fbtft_ssd1322&#8243;.</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/edison/edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17-r0/linux/drivers/video
git add .
git commit
git format-patch -1
</pre>
<p>It created the patch file &#8220;0001-fbtft_ssd1322.patch&#8221;. I renamed it to &#8220;fbtft_ssd1322.patch&#8221; and copied it to:</p>
<pre class="brush: plain; title: ; notranslate">
~edison/edison-src/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/files/
</pre>
<p>I created the kernel configuration file fbtft.cfg in the same directory &#8220;recipes-kernel/linux/files/&#8221;:</p>
<pre class="brush: cpp; title: ; notranslate">
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
</pre>
<p>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.<br />
Then I ran the same git sequence to generate the patch file &#8220;platform_ssd1322.patch&#8221; and copied it into the same &#8220;recipes-kernel/linux/files&#8221; directory.</p>
<pre class="brush: diff; title: ; notranslate">
From c83f14b37bc2dcfa97b36214f02b15ddaad51a47 Mon Sep 17 00:00:00 2001
From: Farit &lt;farit@example.com&gt;
Date: Sat, 9 Apr 2016 22:02:19 -0700
Subject: [PATCH] platform_ssd1322

---
 arch/x86/platform/intel-mid/board.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/platform/intel-mid/board.c b/arch/x86/platform/intel-mid/board.c
index eb3d8a4..fca6440 100644
--- a/arch/x86/platform/intel-mid/board.c
+++ b/arch/x86/platform/intel-mid/board.c
@@ -111,7 +111,7 @@ struct devs_id __initconst device_ids[] = {
 
 	/* SPI devices */
 	{&quot;spidev&quot;, SFI_DEV_TYPE_SPI, 0, &amp;spidev_platform_data, NULL},
-	{&quot;ads7955&quot;, SFI_DEV_TYPE_SPI, 0, &amp;ads7955_platform_data, NULL},
+//	{&quot;ads7955&quot;, SFI_DEV_TYPE_SPI, 0, &amp;ads7955_platform_data, NULL},
 	{&quot;bma023&quot;, SFI_DEV_TYPE_I2C, 1, &amp;no_platform_data, NULL},
 	{&quot;pmic_gpio&quot;, SFI_DEV_TYPE_SPI, 1, &amp;pmic_gpio_platform_data, NULL},
 	{&quot;pmic_gpio&quot;, SFI_DEV_TYPE_IPC, 1, &amp;pmic_gpio_platform_data,
-- 
1.9.1
</pre>
<p>When all patch and configuration files were ready, I added links to them into the file &#8220;~/edison/edison-src/meta-intel-edison/meta-intel-edison-bsp/recipes-kernel/linux/linux-yocto_3.10.bbappend&#8221;.</p>
<pre class="brush: cpp; title: ; notranslate">
SRC_URI += &quot;file://defconfig&quot;
SRC_URI += &quot;file://upstream_to_edison.patch&quot;

SRC_URI += &quot;file://fbtft.cfg&quot;
SRC_URI += &quot;file://fbtft_ssd1322.patch&quot;
SRC_URI += &quot;file://platform_ssd1322.patch&quot;
</pre>
<h5>fbtft Module Compilation</h5>
<p>Then I recompiled the Linux image and installed it.</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/edison/edison-src
source poky/oe-init-build-env
bitbake edison-image
~/edison/edison-src/meta-intel-edison/utils/flash/postBuild.sh
~/edison/edison-src/build/toFlash/flashall.sh
</pre>
<h5>Loading and Testing the Framebuffer Module</h5>
<p>I loaded the fbtft module supplying the name of the display and the SPI bus number (it&#8217;s 5 on the Edison).</p>
<pre class="brush: bash; title: ; notranslate">
modprobe fbtft_device name=er_oled028 busnum=5
</pre>
<p>Sometimes, it&#8217;s not loaded. I need to investigate the problems.<br />
When it loads, the &#8220;dmesg&#8221; command shows:</p>
<pre class="brush: plain; title: ; notranslate">
[   32.254181] fbtft_device:  GPIOS used by 'er_oled028':
[   32.254205] fbtft_device:    'reset' = GPIO49
[   32.254221] fbtft_device:    'dc' = GPIO15
[   32.254234] fbtft_device:    'led' = GPIO14
[   32.254246] fbtft_device:  SPI devices registered:
[   32.254264] fbtft_device:      spidev spi5.1 25000kHz 8 bits mode=0x00
[   32.254281] fbtft_device:      fb_ssd1322 spi5.0 12500kHz 8 bits mode=0x03
[   32.394493] graphics fb0: fb_ssd1322 frame buffer, 256x64, 32 KiB video memory, 8 KiB buffer memory, fps=20, spi5.0 at 12 MHz
</pre>
<p>Then I can test the module by sending random values to the framebuffer socket &#8220;/dev/fb0&#8243;.</p>
<pre class="brush: bash; title: ; notranslate">
cat /dev/urandom &gt; /dev/fb0
</pre>
<p>Here is the result.</p>
<figure id="attachment_117" style="width: 854px;" class="wp-caption aligncenter"><a href="http://hobby.farit.ru/wp-content/uploads/2016/04/display_urandom.png"><img class="size-medium wp-image-117" src="http://hobby.farit.ru/wp-content/uploads/2016/04/display_urandom-854x305.png" alt="Sending Random Data to the Framebuffer" width="854" height="305" /></a><figcaption class="wp-caption-text">Sending Random Data to the Framebuffer</figcaption></figure>
<p>I can also load the fbcon module to display the console on the display.</p>
<pre class="brush: bash; title: ; notranslate">
modprobe fbcon
</pre>
<figure id="attachment_118" style="width: 854px;" class="wp-caption aligncenter"><a href="http://hobby.farit.ru/wp-content/uploads/2016/04/fbcon.png"><img class="size-medium wp-image-118" src="http://hobby.farit.ru/wp-content/uploads/2016/04/fbcon-854x291.png" alt="Edison Console via the Framebuffer" width="854" height="291" /></a><figcaption class="wp-caption-text">Edison Console via the Framebuffer</figcaption></figure>
<h5>Improvements</h5>
<p>There are patches on the Edison forum that may help to fix the DMA issue. Otherwise, the display will be relatively slow.<br />
Check this link <a href="https://communities.intel.com/docs/DOC-24944" target="_blank">stewart maguire&#8217;s patches for DMA and FBTFT support</a>.<br />
And this <a href="https://communities.intel.com/thread/76768?start=0&amp;tstart=0" target="_blank">Intel MID SSP SPI driver getting stuck in kernel space</a>.</p>
<h5>Downloads</h5>
<p><a href="http://hobby.farit.ru/wp-content/uploads/2016/04/ssd1322patch.tar.gz">Configuration and patch files for fbtft on Intel Edison</a></p>
]]></content:encoded>
			<wfw:commentRss>https://hobby.farit.ru/framebuffer-fbtft-installation-intel-edison-oled-display-ssd1322/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building Yocto Linux for Intel Edison</title>
		<link>https://hobby.farit.ru/building-yocto-linux-for-intel-edison/</link>
		<comments>https://hobby.farit.ru/building-yocto-linux-for-intel-edison/#comments</comments>
		<pubDate>Sat, 01 Aug 2015 04:39:11 +0000</pubDate>
		<dc:creator><![CDATA[Farit]]></dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[intel edison]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[yocto]]></category>

		<guid isPermaLink="false">http://hobby.farit.ru/?p=84</guid>
		<description><![CDATA[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&#8217;s not as convenient as Ubuntu as there are no pre-compiled packages that are easy to install. I wanted [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>The Intel Edison board is shipped with the <a href="https://www.yoctoproject.org/" target="_blank"><strong>Yocto</strong></a> 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&#8217;s not as convenient as Ubuntu as there are no pre-compiled packages that are easy to install.</p>
<p>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&#8217;ll describe them here.</p>
<p>The main document is <strong><a href="http://www.intel.com/support/edison/sb/CS-035278.htm" target="_blank">Board Support Package (BSP) User Guide</a></strong>. I followed it.</p>
<p>Installed the prerequisite packages with the following command:</p>
<pre class="brush: plain; title: ; notranslate">
sudo apt-get install build-essential git diffstat gawk chrpath texinfo libtool \
gcc-multilib dfu-util u-boot-tools
</pre>
<p>Set up my git name and email:</p>
<pre class="brush: plain; title: ; notranslate">
git config --global user.name &quot;YOUR NAME&quot;
git config --global user.email &quot;YOUR EMAIL ADDRESS&quot;
</pre>
<p>Downloaded the package <strong>Linux source files</strong> from the <a href="https://software.intel.com/iot/hardware/edison/downloads" target="_blank"><strong>Intel Edison Software Downloads</strong></a> page. At the time of writing, it was in the section <strong>Intel Edison® Board Firmware Software Release 2.1</strong>.</p>
<p>I install everything related to the Intel Edison into the directory /home/farit/edison. The Linux sources consume 11G in that directory.</p>
<p>Decompressed the source package:</p>
<pre class="brush: plain; title: ; notranslate">
tar xzf edison-src-ww25.5-15.tgz  -C /home/farit/edison/
cd /home/farit/edison/edison-src/
</pre>
<p>Moved my download and build cache (also called sstate) directories from the default location under the build directory, using the &#8211;dl_dir and &#8211;sstate_dir options. To create download and sstate directory, used the mkdir command:</p>
<pre class="brush: plain; title: ; notranslate">
mkdir /home/farit/edison/bitbake_download_dir
mkdir /home/farit/edison/bitbake_sstate_dir
</pre>
<p>Used the setup.sh script to initialize the build environment for Intel Edison.</p>
<pre class="brush: plain; title: ; notranslate">
/home/farit/edison/edison-src/meta-intel-edison/setup.sh \
--dl_dir=/home/farit/edison/bitbake_download_dir \
--sstate_dir=/home/farit/edison/bitbake_sstate_dir \
--build_dir=/home/farit/edison/edison-src
</pre>
<p>After the setup, I ran these commands recommended by the setup script:</p>
<pre class="brush: plain; title: ; notranslate">
cd /home/farit/edison/edison-src
source poky/oe-init-build-env
bitbake edison-image
</pre>
<p>The compilation took 5 or so hours. I should&#8217;ve used the SSD disk. But most files have been downloaded and cached now; so, it doesn&#8217;t take much time the second time.</p>
<p>Then I decided to compile in Midnight Commander. I checked the name of the package on the <a href="http://packages.yoctoproject.org/" target="_blank">Yocto recipes directory</a>. It was &#8220;mc&#8221;.<br />
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:</p>
<pre class="brush: plain; title: ; notranslate">
#Midnight Commander
IMAGE_INSTALL += &quot;mc&quot;
</pre>
<p>Then ran again:</p>
<pre class="brush: plain; title: ; notranslate">
cd /home/farit/edison/edison-src
source poky/oe-init-build-env
bitbake edison-image
</pre>
<p>Then I created a new Linux image:</p>
<pre class="brush: plain; title: ; notranslate">
/home/farit/edison/edison-src/meta-intel-edison/utils/flash/postBuild.sh
/home/farit/edison/edison-src/build/toFlash/flashall.sh
</pre>
<p>At first, the command complained about the non-existing mkimage program, which is in the package u-boot-tools:</p>
<pre class="brush: plain; title: ; notranslate">
Error : ota_update.scr creation failed, mkimage tool not found
</pre>
<p>I added a symlink to mkimage and ran the postBuild.sh script again:</p>
<pre class="brush: plain; title: ; notranslate">
cd /home/farit/edison/edison-src
mkdir -p u-boot/tools
cd u-boot/tools
ln -s /usr/bin/mkimage mkimage
</pre>
<p>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&#8217;s firmware image.<br />
I ran the command flashall.sh in it as root. I added myself into the group &#8220;dialout&#8221;; so, I should be able to connect to a USB port as a regular user. I&#8217;ll check it again the next time.</p>
<figure id="attachment_87" style="width: 854px;" class="wp-caption alignnone"><a href="http://hobby.farit.ru/wp-content/uploads/2015/07/mc_edison.png"><img class="size-medium wp-image-87" src="http://hobby.farit.ru/wp-content/uploads/2015/07/mc_edison-854x463.png" alt="Midnight Commander on Intel Edison" width="854" height="463" /></a><figcaption class="wp-caption-text">Midnight Commander on Intel Edison</figcaption></figure>
<p>By default, the subshell (Ctrl-O) doesn&#8217;t work in Midnight Commander as it requires bash. Change your user shell from the default &#8220;/bin/sh&#8221; to &#8220;/bin/bash&#8221; in /etc/passwd.</p>
<p>When I want to quickly recompile just the kernel after changes, I run these commands:</p>
<pre class="brush: plain; title: ; notranslate">
cd /home/farit/edison/edison-src
source poky/oe-init-build-env
bitbake -f linux-yocto
</pre>
]]></content:encoded>
			<wfw:commentRss>https://hobby.farit.ru/building-yocto-linux-for-intel-edison/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
