Пост содержит инструкцию как подключить TFT-LCD дисплей на популярном контроллере ILI9341 к одноплатному компьютеру на ОС Armbian с помощью дерева устройств (Device Tree overlays) без танцев с бубном. В сети Интернет много материала как подключать различные LCD экраны к Raspberry Pi. Но что если у вас нет Raspberry Pi, а хочется подключить недорогой LCD экран на SPI интерфейсе? Все что вам необходимо, это любая плата с поддержкой ОС Armbian. В каталог поддерживаемых плат ОС Armbian входят платы: Asus, Pine64, Hardkernel, Orange Pi, Banana Pi, и т.д. На данный момент в каталоге более 114 моделей плат, объявлена поддержка различного оборудования из коробки. Доступны для подключения: 4G/LTE модемы, USB Wi-Fi, USB Bluetooth, USB Ethernet, сканеры DVB-тюнеры и т.д. К всем этим платам можно легко подключить SPI LCD дисплей ILI9341, как это реализовать прошу под кат.
Преамбула
Многие одноплатные компьютеры снабжены HDMI выходом, но подключение полноценного дисплея с поддержкой HDMI входа достаточно дорогое удовольствие для небольшого проекта. В особенности, если необходимо реализовать минимальный функционал взаимодействия с пользователем, терминал распечатки документов, вывод текущего статуса работающего приложения. Для подобных задач можно использовать символьные дисплеи LCD HD44780 на интерфейсе I2C, они достаточно дешевы и удобны. Но в тоже время сильно ограничены в функциональности, на эти экраны невозможно вывести консоль Linux и нативный UI приложения, вдобавок площадь LCD экрана нельзя использовать как панель ввода информации. Для решения этих задач прекрасно подойдут LCD экраны на SPI интерфейсе, дисплей диагональю 3.5 дюйма с резистивным слоем можно приобрести за 9.57$ (включая доставку). На LCD экран можно выводить консоль Linux и подсистему X11. Таким образом, использование SPI LCD является лучшим вариантом по соотношению функциональности к стоимости.
Дисплей ILI9341 2.2 inch 2.2" SPI TFT
Контроллер ILI9341 предназначен для управления TFT панелью. Под контроллер ILI9341 поставляются панели диагональю от 2.2 до 3.2 дюймов, разрешение 240x320, к некоторым LCD добавляют резистивный слой.
К одноплатному компьютеру Banana Pi BPI-M64 будем подключать модуль SPI LCD ILI9341 диагональю 2.4 дюйма без резистивного слоя.
Рассмотрим характеристики и распиновку SPI LCD ILI9341 2.4 inch
- 2,4-дюймовый цветной экран, поддержка 65K цветов
- разрешение 320X240
- интерфейс подключения SPI
- доступен слот для SD-карты
- питание модуля 3.3V~5V
- Напряжение управления логикой 3.3V(TTL)
Контакты подключения LCD
Number | Pin Label | Description |
1 | VCC | 5V/3.3V power input |
2 | GND | Ground |
3 | CS | LCD chip select signal, low level enable |
4 | RESET | LCD reset signal, low level reset |
5 | DC/RS | LCD register / data selection signal,high level: register, low level: data |
6 | SDI(MOSI) | SPI bus write data signal |
7 | SCK | SPI bus clock signal |
8 | LED | Backlight control, high level lighting,if not controlled, connect 3.3V always bright |
9 | SDO(MISO) | SPI bus read data signal, if you do not need to the read function, you can not connect it |
Для управления подсветки используется контакт номер 8 — LED. Максимальное напряжение 3.3V соответствует максимальной яркости от общего питания VCC. Если необходимо задать 50% яркости экрана, то на LED необходимо подать напряжение в 1.65V. Для программного управления яркости подсветки необходимо контакт LED подключать к аналоговому выходу GPIO на одноплатном компьютере. В случае наличия только цифровых выходов, доступна лишь возможности включить или полностью выключить подсветку экрана.
Исходя из характеристик LCD экрана предъявляются следующие требования к одноплатному компьютеру:
- наличие SPI интерфейса
- напряжение логики на контактах 3.3V (большинство плат)
- потребуется еще два (RESET, DC/RS) свободных контактов GPIO
Что ты за зверь Armbian и какой одноплатный компьютер необходим
На странице armbian.com/download представлено большое количество разнообразных одноплатных компьютеров. С точки зрения удобства подключения, лучше выбирать плату с 40-контактным разъемом GPIO совместимым с Raspberry Pi 3. Например, если подключать SPI LCD ILI9341 2.4 inch к плате Banana Pi BPI-M64 и Orange Pi PC, то номера физически подключаемых контактов GPIO будут совпадать (не путать с названиями контактов процессора, они будут различны, далее потребуется для конфигурирования). В случае если одноплатный компьютер будет построена не на процессоре Allwinner, то возможно потребуется изменять больше параметров в файле: sun50i-a64-spi-ili9341-led-always-on.dts (будет далее по тексту).
Armbian — это самый популярный дистрибутив Linux, предназначенный для одноплатных компьютеров построенных на ARM процессоре, список поддерживаемых плат огромен: Orange Pi, Banana Pi, Odroid, Olimex, Cubieboard, Roseapple Pi, Pine64, NanoPi и др. Дистрибутив Armbain основан на Debian и Ubuntu.
После явления миру Raspberry Pi, китайские производители решили тоже влиться в движение Open Hardware Source, и сделали много разнообразных плат. Но программная поддержка была крайне слабой, для решения данной проблемы зародился проект Armbian. На данный момент Armbian уже исполнилось 7 лет, поддерживается 114 моделей плат, объявлена поддержка различного оборудования из коробки. Доступны для подключения: 4G/LTE модемы, USB Wi-Fi, USB Bluetooth, USB Ethernet, сканеры DVB-тюнеры и т.д.
Для запуска Armbian на одноплатном компьютере необходимо загрузить образ с сайта, затем скопировать его на microSD карту, с которой в последствие нужно будет загрузиться. Если на плате размещена eMMC память достаточного объема, то через утилиту armbian-config, операционная система легко переносится с microSD карты на eMMC память вместе с загрузчиком.
Создание IoT-проекта с использованием Armbian в отличие от Raspberry Pi, позволяет выбирать платы различающие по производительности, и набора периферии. Например, на всех версиях Raspberry Pi размещен только один Ethernet порт. Но если требуется сделать маршрутизатор с несколькими Ethernet портами, то из списка поддерживаемых плат Armbian подойдут модели: Helios64, Espressobin, Bananapi R2, и т.д.
Поддерживаемые SoC
- Allwinner A10, A20, A31, H2+, H3, H5, H6, A64
- Amlogic S805 and S905 (Odroid boards), S802/S812, S805, S905, S905X and S912 (fork by @balbes150)
- Actionsemi S500
- Freescale / NXP iMx6
- Marvell Armada A380
- Rockchip RK3288/RK3328/RK3399
- Samsung Exynos 5422
Схема подключения SPI LCD ILI9341 2.4 inch к Banana Pi BPI-M64 (порт GPIO Raspberry Pi 3)
SPI интерфейс LCD экрана подключаем к SPI1 на Banana Pi BPI-M64. Контакты CS, RESET, DC/RS можно подключать к любым цифровым выводам.
Таблица контактов подключения:
Номер LCD | Метка LCD | Номер контакта на Banana Pi BPI-M64 (порт GPIO Raspberry Pi 3) |
1 | VCC | 1 или 2 (если необходима максимальная яркость, то контакт №2 на 5V) |
2 | GND | 39, или любой другой Ground |
3 | CS | 24 |
4 | RESET | 18 |
5 | DC/RS | 22 |
6 | SDI(MOSI) | 19 |
7 | SCK | 23 |
8 | LED | 1 или любой свободный GPIO на 3.3V |
9 | SDO(MISO) | 21 |
Если контакт LED подключать к цифровому выводу GPIO, то для включения подсветки вручную потребуется подавать логическую «1» — для включения или «0» — для выключения экрана.
Схема подключения SPI LCD ILI9341:
Одноплатный компьютер Banana Pi BPI-M64
Banana Pi BPI-M64 — это 64-битный четырехъядерный мини-одноплатный компьютер, поставляемый как решение с открытым исходном кодом. Ядром системы является процессор Allwinner A64 с 4-мя ядрами Cortex-A53 с частотой 1.2 ГГц. На плате размещено 2 ГБ DDR3 SDRAM 733МГц оперативной памяти и 8 ГБ eMMC.
Самое главное для успешного подключения SPI LCD необходимо знать название контактов для SPI интерфейса, их номер и название зависит от модели процессора. Для решения этой задачи необходим Allwinner A64 Datasheet. На Wiki-странице Banana Pi BPI-M64 представлена распиновка 40-контактного разъема GPIO, из которого мы узнаем название контактов: PD2, PD3, и т.д.
40 PIN GPIO of Banana pi BPI-M64 | |||
GPIO Pin Name | Default Function | Function2:GPIO | Function3 |
CON2-P18 | PD4 | PD4 | |
CON2-P19 | SPI1-MOSI | PD2 | UART4-TX |
CON2-P21 | SPI1-MISO | PD3 | UART4-RX |
CON2-P22 | PC0 | PC0 | |
CON2-P23 | SPI1-CLK | PD1 | UART3-RX |
CON2-P24 | SPI1-CS | PD0 | UART3-TX |
Помимо название контакта, необходимо узнать порядковый номер этого контакта на ножке процессора, легко вычисляется по формуле: (позиция буквы в алфавите — 1) * 32 + позиция вывода. Рассчитаем номер ножки для контакта PD2. Первая буква не учитывается т.к. P — PORT, позиция буквы D в алфавите = 4, получаем (4-1) * 32 + 2 = 98. Контакту с меткой PD2 соответствует 98 ножка на процессоре, далее потребуется для конфигурирования дерева устройств.
Дерево устройств (Device Tree, DT) в Linux
Дерево устройств (Device Tree, DT) — это структура данных в системе Linux, состоящая из именованных узлов и свойств, описывающих оборудование, которое невозможно обнаружить путем опроса оборудования. Дерево должно включать имя базового процессора, конфигурацию его памяти и любые периферийные устройства (внутренние и внешние). DT не используется для описания программного обеспечения, хотя перечисление аппаратных модулей вызывает загрузку модулей драйверов.
Сердцем любой отладочной платы или одноплатного компьютера является SoC. SoC имеет множество контактов (ног) для подключения линий электропитания и различных устройств.
Контакты могут быть объедены вместе для формирования интерфейса, например MIPI DSI(MIPI Display Serial Interface). Интерфейс MIPI DSI предназначен для подключения LCD панелей, активно используется в смартфонах и планшетах. Но если к устройству не планируется подключать дисплей по MIPI DSI, то эти линии можно использовать для других целей, путем изменения DT. В отличие от архитектуры x86 в системах построенных на SoC нет возможности произвести полностью опознание всех устройств в режиме Plug and Play. Поэтому необходимо явное декларирование какие контакты используются для интерфейсов и какие именно устройства подключены к этим интерфейсам.
До появления DT информация об устройствах в Linux являлась неотъемлемой частью ядра, и в случае изменения состава периферийных устройств требовалось пересобрать образ системы. Это было крайне неудобно, и поэтому описание периферийных устройств перенесли в конфигурационные файлы, которые собираются на логическом уровне в дерево. Где ветвь — устройство с указанием драйвера необходимого для работы этого устройства.
После использования DT отпала необходимость в формирование индивидуального образа для каждого набора периферии устройств. Теперь достаточно сформировать один образ, включить в него набор драйверов для различных устройств, и для каждого устройства сформировать свой DT.
Наложения дерева устройств (Device Tree overlays)
Device Tree overlays (наложения дерева устройств) — добавление к DT принципа наложения слоев устройств. Если конфигурация описывает интерфейс UART к которому был подключен Bluetooth, и необходимо Bluetooth заменить на GPS модуль, то можно не удалять существующие настройки Bluetooth а добавить дополнительный слой для GPS модуля который переопределит предыдущие настройки.
Для работы с DT используются следующие термины:
DT | Дерево устройств |
DTB (*.dtb) | Бинарный файл дерева устройств |
DTBO (*.dtbo) | Бинарный файл дерева устройств для наложения |
DTC | Компилятор дерева устройств |
DTO | Наложения дерева устройств |
DTS (*.dts) | Исходный файл для дерева устройств |
FDT | Flattened Device Tree, двоичный формат, содержащийся в файле .dtb |
Аппаратная конфигурация описывается в файлах исходниках DT ( .dts ) затем они компилируется в бинарные файлы DT ( .dtb ) уже для конечного использования в системе. Так же можно выполнить обратную процедуру декомпиляции файлов *. dtb в *. dts, компилятор/декомпилятор присутствует в системе.
Реализация DTO включает разделение дерева устройств, построение, разбиение на разделы и исполнение.
Разделение DT
DT разделяются на две части:
- Main DT (основное дерево устройств). Предоставляет разработчик SoC и является настройкой по умолчанию. В данном случае предоставляет компания Allwinner разработчик процессора Allwinner A64.
- Overlay DT (Накладываемое дерево устройств). Специфическая конфигурация производителя платы, включает периферийные устройства которые размещены на плате. Для платы Banana Pi BPI-M64 предоставляет компания SinoVoip Co.,
Тема Device Tree overlays в Linux достаточно большая, чтобы не превращать пост в многотомное произведение Ленина, более детально можно почитать в публикации Работа с GPIO на примере Banana Pi BPI-M64. Часть 2. Device Tree overlays.
Формирование DTS для SPI LCD ILI9341 2.4 inch
Тестирование производилось на образе Armbian_20.08.2_Bananapim64_bionic_current_5.8.6_minimal.img.xz, на основе Ubuntu 18.04.5 LTS (Bionic Beaver), ядро Linux 5.8.6. uname: Linux bananapim64 5.8.6-sunxi64 #20.08.2 SMP Fri Sep 4 08:52:31 CEST 2020 aarch64 aarch64 aarch64 GNU/Linux.
В Armbian уже есть драйвер для ILI9341, поэтому все что требуется, это создать файл описания устройства в формате DTS, скомпилировать его в формат DTBO, и перезагрузить одноплатный компьютер. Как говорится Easy!
Для формирования файла DTS необходимо узнать ссылку на gpiochip в котором находится SPI интерфейс, для этого откроем терминал Armbian и выполним команду cat /sys/kernel/debug/gpio:
root@bananapim64:~# cat /sys/kernel/debug/gpio
gpiochip1: GPIOs 0-255, parent: platform/1c20800.pinctrl, 1c20800.pinctrl:
gpio-120 ( |bananapi-m64:red:pwr) out hi
gpio-142 ( |bananapi-m64:green:u) out lo
gpio-143 ( |bananapi-m64:blue:us) out lo
gpio-166 ( |cd ) in lo ACTIVE LOW
gpio-233 ( |usb0_id_det ) in hi IRQ
gpiochip0: GPIOs 352-383, parent: platform/1f02c00.pinctrl, 1f02c00.pinctrl:
gpio-354 ( |reset ) out hi ACTIVE LOW
gpio-356 ( |shutdown ) out hi
gpio-357 ( |host-wakeup ) in lo
gpio-358 ( |device-wakeup ) out hi
gpiochip2: GPIOs 510-511, parent: platform/axp20x-gpio, axp20x-gpio, can sleep:
Данная команда выведет все доступные устройства gpiochip и номера задействованных контактов в операционной системе. В предыдущем разделе для контакта SPI1-MOSI, название контакта PD2, определили номер ножки процессора — 98. Исходя из полученного результата номер 98 приходится на диапазон GPIOs 0-255, который соответствует чипу gpiochip1: GPIOs 0-255, parent: platform/1c20800.pinctrl, 1c20800.pinctrl. Далее для формирования файла DTS потребуется узнать ссылку на 1c20800.pinctrl.
Создадим файл DTS с названием: sun50i-a64-spi-ili9341-led-always-on.dts (в основе dts файл для платы Orange Pi PC):
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun8i-h3";
fragment@0 {
target = <&pio>;
__overlay__ {
ili9341_pins: ili9341_pins {
pins = "PD4", "PC0"; /*RESET, DC_RS*/
function = "gpio_out", "gpio_out" ;
};
};
};
fragment@1 {
target = <&spi1>;
__overlay__ {
status = "okay";
cs-gpios = <&pio 3 0 0>; /* PD0 */
ili9341: ili9341@0 {
compatible = "ilitek,ili9341";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&ili9341_pins>;
spi-max-frequency = <16000000>;
rotate = <90>;
bgr;
fps = <25>;
buswidth = <8>;
reset-gpios = <&pio 3 4 1>; /*RESET=PD4*/
dc-gpios = <&pio 2 0 0>; /*DC_RS=PC0*/
/*led-gpios = <&pio 2 4 0>; LED=PC4*/
debug = <0>;
};
};
};
};
Рассмотрим содержимое:
- fragment@0 — является наложением на блок узла /soc/pinctrl@1c20800, ссылка этого узла &pio. Описывает название задействованных контактов GPIO PD4", «PC0 и определяет функцию gpio_out для контактов.
- &pio — это ссылка в дереве устройств для контактов GPIO на узел /soc/pinctrl@1c20800, название определяли выше. Ссылка берется из файла в Armbian по пути: /boot/dtb-5.8.6-sunxi64/allwinner/sun50i-a64-bananapi-m64.dtb. Для компиляции в формат DTS, выполнить команду: $ dtc -I dtb -O dts sun50i-a64-bananapi-m64.dtb -o sun50i-a64-bananapi-m64.dts
- fragment@1 — является наложением на блок узла /soc/spi@1c69000, ссылка этого узла &spi1.
- status = „okay“ — задействует SPI1 интерфейс на плате для подключения устройств
- cs-gpios = <&pio 3 0 0>; /* PD0 */ — номер контакта для CS интерфейса SPI1.
- <&pio 3 0 0> — параметры контакта, где &pio ссылка на gpioiochip1 в основном дереве устройств, буква P не учитывается, означает PORT, буква D — кодируется в цифру 3 (формула: порядковый номер буквы в алфавите — 1), 0 после цифры 3 это позиция вывода, 0 из PD0, и последний 0 — означает полярность, по умолчанию всегда 0 (полярность 0 — на логический ноль, выдается напряжение 0; полярность 1 — на логический ноль, выдается напряжение 1).
- compatible = „ilitek,ili9341“ — идентификатор драйвера для данного устройства
- pinctrl-0 = <&ili9341_pins> — ссылка на используемые контакты из fragment@0
- spi-max-frequency = <16000000> — частота работы SPI интерфейса
- rotate = <90> — ориентация изображения, поворот на 90 градусов, в зависимости как необходимо расположить дисплей.
- fps = <25> — кадров в секунду
- reset-gpios = <&pio 3 4 1> — контакт RESET=PD4
- dc-gpios = <&pio 2 0 0> — контакт DC_RS=PC0
Разместим файл по пути /boot/dtb/allwinner/overlay. Затем компилирует файл .dts в .dtbo:
$ dtc -O dtb -o sun50i-a64-spi-ili9341-led-always-on.dtbo sun50i-a64-spi-ili9341-led-always-on.dts
Запустим утилиту конфигурирования платы: $ armbian-config. Перейдем по меню: System > Hardware, и включим слой (overlay): spi-ili9341-led-always-on. После перезагрузки платы, консоль Linux будет на SPI LCD экране:
Название контактов
Для всех процессоров Allwinner формат записи контакта, соответствует виду cs-gpios = <&pio 3 0 0>, для других процессоров формат записи контакта будет отличаться.
Решение проблем
Если изображение не появилось на LCD, выполните команду для проверки: $ dmesg | grep -E 'ili9341'.
В консоли должна быть следующая информация:
root@bananapim64:/boot/dtb-5.8.6-sunxi64/allwinner# dmesg | grep -E 'ili9341'
[ 5.733989] fb_ili9341: module is from the staging directory, the quality is unknown, you have been warned.
[ 5.734718] fb_ili9341 spi0.0: fbtft_property_value: buswidth = 8
[ 5.734731] fb_ili9341 spi0.0: fbtft_property_value: debug = 0
[ 5.734737] fb_ili9341 spi0.0: fbtft_property_value: rotate = 90
[ 5.734744] fb_ili9341 spi0.0: fbtft_property_value: fps = 25
[ 6.119287] graphics fb0: fb_ili9341 frame buffer, 320x240, 150 KiB video memory, 16 KiB buffer memory, fps=25, spi0.0 at 16 MHz
Настройка SPI LCD для графического интерфейса Xfce и подсистемы X11
Для вывода консоли Linux достаточно добавить файл DTS и все, но для вывода графики этого недостаточно.
1) Установим XORG и XFCE:
$ sudo apt-get update
$ sudo apt-get install xorg
$ sudo apt-get install xfce4
2) Для процессора Allwinner необходимо дополнительно устанавливать GPU драйвер — fbdev:
$ sudo apt-get install xserver-xorg-video-fbdev
3) Удалить все конфигурационные файлы по пути /etc/X11/xorg.conf.d (если нет файлов, то отлично)
4) Создать конфигурационный файл по пути /usr/share/X11/xorg.conf.d/99-fbdev.conf и разместить в нем следующий фрагмент:
Section "Device"
Identifier "myfb"
Driver "fbdev"
Option "fbdev" "/dev/fb0"
EndSection
Где /dev/fb0 — устройство SPI LCD. Если к плате подключена HDMI панель, то может быть два устройства /dev/fb0 и /dev/fb1.
Запускаем графический интерфейс командой: startx или startxfсe4:
Если необходимо сразу переходить в графический интерфейс, то необходимо дополнительно установить пакеты:
$ sudo apt-get remove tasksel
$ sudo apt-get remove xubuntu-desktop
Для возвращения запуска только консоли необходимо отключить автозапуск службы display-manager.service
$ sudo systemctl disable display-manager.service
Решение проблем
Если графический интерфейс не запускается то для решение проблем необходимо посмотреть журнал событий X11, командой:
$ cat /var/log/Xorg.0.log
Итог
Установка и настройка SPI LCD не требует никаких компиляций модулей из исходного текста, что существенно упрощает установку. Главное внимательно выставить контакты и все заработает из коробки. Поставленные цели успешно решены.
RoadMap
- Подключение дисплея большего размера 3.5 дюйма на контроллере ILI9488.
- Настройка Touch интерфейса для Xfсe.
- Вывод на SPI LCD только одного графического приложения используя подсистему X11 из Docker контейнера (решение для публичных терминалов, киосков, POS-терминалов).
Файл sun50i-a64-spi-ili9341-led-always-on.dts и другие файлы наложения дерева доступны в каталоге GitHub Banana-Pi-BPI-M64/dt-overlays/
devzona Автор
Ребята очень хорошо рассказывают про Device Tree Overlay на конференции Linux Piter 2016. Доклад рассказывает о основах технологии device tree, позволяющей абстрагироваться от аппаратной специфики при работе с ядром Linux.