Как перестать бояться и полюбить mbed [Часть 2]

в 10:34, , рубрики: atmel, FT800, HYT, IST, mbed, SiLabs, Wiznet, Блог компании ЭФО, программирование микроконтроллеров, Промышленное программирование, Разработка для интернета вещей, Разработка робототехники

Продолжаем серию публикаций, посвященных использованию среды ARM mbed для создания прототипа измерительного устройства.

Напомню, что речь идет о разработке устройства с сенсорным экраном, которое служит для высокоскоростного измерения температуры и относительной влажности. Самое интересное в этой истории — подход к созданию встроенного ПО. Для написания программы используется онлайн IDE mbed, позволяющая создавать железонезависимый код, который одинаково работает на отладочных платах от SiLabs, Atmel, Wiznet, STM32, NXP и других производителей.

Сегодня начинаем работать с выводом картинки на TFT-дисплей.

Как перестать бояться и полюбить mbed [Часть 2] - 1

Содержание цикла публикаций:

  1. Обзор использованных программных и аппаратных решений.
  2. Начало работы с графическим контроллером FT800. Использование готовых mbed-библиотек для периферийных устройств.
  3. Подключение датчика HYT-271. Создание и публикация в mbed собственной библиотеки для периферийных устройств.
  4. Разработка приложения: Структура программы, работа с сенсорным экраном.
  5. Разработка приложения: Вывод изображений на дисплей, проблемы русификации.
  6. Печать деталей корпуса. Анализ ошибок проектирования и другие выводы.

Вторая часть под катом.

В прошлой статье был дан краткий обзор использованных аппаратных модулей, в том числе сенсорного TFT-дисплея — модуля от компании Riverdi, который состоит из дисплея и встроенного графического контроллера FT800 от FTDI. Сегодня мы рассмотрим общие вопросы работы с таким модулем и «подружим» его с отладочной платой.

Поскольку для написания ПО используется исключительно онлайн IDE mbed, получившаяся программа должна без проблем запуститься на отладочных платах SLSTK3400A от SiLabs, ATSAMD21-XPRO от Atmel и WIZwiki-W7500P от Wiznet.

Как перестать бояться и полюбить mbed [Часть 2] - 2



Итак, все процедуры, связанные с выводом графики, сенсорным вводом и работой аудиоканала, аппаратно реализованы на графическом контроллере серии FT800. Задачей разработчика является управление микросхемой FTDI с главного микроконтроллера — грубо говоря, чтение и запись определенных регистров контроллера FT800 по интерфейсу SPI или I2C*.
* далее будем считать что хост-контроллер связан с FT800 по интерфейсу SPI. Чаще всего так и есть.

Как перестать бояться и полюбить mbed [Часть 2] - 3
Для управления графическим контроллером используются команды трех типов:

  • Host command для управления режимом работы FT800,
  • Host Memory Read для получения информации с контроллера FTDI (например, для чтения регистра сенсорного ввода)
  • Host Memory Write для передачи команд на выполнение графических операций, на воспроизведение звука и т.д.

Все функции для взаимодействия с TFT-дисплеем состоят из приема и передачи таких команд. Компания FTDI предоставляет библиотеку, в которой реализованы все операции, поддерживаемые графическим контроллером. Это несколько десятков функций различной сложности, которые, тем не менее, всегда состоят их базовых функций — приема и передачи по SPI инструкций Host command, Host Memory Read и Host Memory Write.

В общем случае для начала работы с дисплеем требуется адаптировать под используемый хост-контроллер те функции библиотеки FTDI, которые обращаются к периферийным устройствам управляющего контроллера. Это настройка интерфейса SPI, а также функции чтения и записи по SPI данных заданного формата. После того, как железозависимые функции изменены в соответствии с особенностями хост-контроллера, можно начинать использовать все возможности библиотек и примеров от FTDI.

О том, где скачать библиотеку и примеры для модулей FT800, о том как адаптировать библиотеку под целевой хост-микроконтроллер и как использовать доступные функции для практических задач, можно узнать из материалов от производителя и из статей моего коллеги Сергея Долгушина:

Материалы от производителя
По ссылке доступен полный список материалов. Лично я рекомендую начать с AN_240 FT800 From the Ground Up, продолжить документом FT800 Series Programmers Guide, а далее искать документы связанные непосредственно с вашей задачей.

Подборка статей на русском языке
  1. Графический контроллер FT800 для управления TFT-дисплеями – обзорная статья, которая знакомит с основными возможностями графических контроллеров FTDI.
  2. Графический контроллер FT800. Программные средства разработки и отладки. – в статье рассмотрены полезные утилиты и библиотеки, которые существенно упрощают этапы освоения, разработки и тестирования графических приложений, а также помогают познакомиться с функциональными возможностями FT800/801 с помощью персонального компьютера без использования дополнительных аппаратных средств.
  3. Начинаем работать с графическим контроллером FT800 FTDI – пример использования графического контроллера FT800 с микроконтроллерами Cypress. Описаны основные этапы по адаптации библиотеки производителя для выбранного МК.
  4. Графический контроллер EVE FT800 FTDI. Работа с пользовательскими шрифтами, кнопками и сенсорным экраном. – продолжение предыдущей статьи, в которой рассмотрены основные принципы работы с элементами пользовательского интерфейса и сенсорным экраном. В частности, показано, как FT80x обрабатывает информацию от сенсорного экрана и автоматически привязывает ее к заданному элементу интерфейса.
  5. Графический контроллер EVE FT800 FTDI и микроконтроллер SAMD21 Atmel. Работаем с графическими изображениями. – Пример адаптации библиотеки производителя для использования с МК Atmel серии SAM D21 и работа с графическими объектами.
  6. Графический контроллер EVE FT800 FTDI и микроконтроллер SAMD21 Atmel. – продолжение предыдущей статьи, в которой описана методика работы с JPEG-изображениями.
  7. Графический контроллер FT800. Вывод на экран изображения стрелочного индикатора – в данном примере описана методика, которая позволяет минимизировать обмен данными между МК и графическим контроллером за счет использования встроенного ОЗУ FT80x.

В случае разработки программы в mbed задача упрощается ещё сильнее — поскольку написанный в mbed код сам по себе является железонезависимыми, то даже базовые функции библиотеки FTDI становятся универсальными. Таким образом, для управлением дисплеем с отладочных плат от разных производителей можно использовать одну и ту же mbed-библиотеку без внесения каких-либо изменений.

Схема подключения


Для подключения TFT-модуля требуется восемь сигналов:

  • четыре линии SPI — mosi, miso, sck и ss
  • Сигнал intr (interrupt от контроллера FTD хост-контроллеру),
  • Сигнал pd — power down,
  • Питание (3.3 В) и земля.

Сигналы intr и pd могут быть реализованы на любых свободных цифровых линиях хост-контроллера.

Как перестать бояться и полюбить mbed [Часть 2] - 4

Для большинства TFT-модулей Riverdi подключение модуля к управляющему контроллеру производится через плоский шлейф. Для подключения шлейфа к отладочным платам предлагается плата-переходник Break Out Board 20. При её использовании нужно обратить внимание на то, что кроме линии питания VDD, на плате отдельно выведено питание подсветки дисплея — сигнал BLVDD. Для работы с дисплеем питание должно подаваться и на VDD, и на BLVDD, поэтому есть смысл сразу объединить линии и подавать питание только на VDD.

Как перестать бояться и полюбить mbed [Часть 2] - 5
С землями GND и BLGND такой фокус не требуется.

Процедура инициализации TFT-модуля


Как перестать бояться и полюбить mbed [Часть 2] - 6Процедура инициализации состоит из трех этапов: настройка интерфейса SPI, инициализация графического контроллера FT800 и инициализация TFT-дисплея.

Интерфейс SPI хост-процессора всегда является мастером и работает в режиме “mode 0” с передачей старшего бита первым (MSB first). Максимальная рабочая частота интерфейса — 30 МГц, однако до окончания процедуры инициализации частота не должна быть задана выше 11 МГц.

Инициализация графического контроллера состоит в последовательном выполнении следующих операций.

Сначала сигнал PD переводится на 20 мс в низкий уровень, а затем ещё на 20 мс в высокий уровень. Таким образом графический контроллер переходит в режим готовности (Standby). После этого на контроллер FTDI подается несколько команд группы Host command: командой ACTIVE (0x00) контроллер переводится в активный режим, командой CORERST (0x68) сбрасываются значения всех регистров и логических цепей, далее командой CLKEXT (0x44) выбирается тактирование от внешнего источника, а после этого выбирается рабочая частота контроллера — 48 или 36 МГц командой CLK48M (0x62) или CLK36M (0x61) соответственно.

Конечно, возможны и другие сценарии настройки контроллера FT800, но чаще всего процедура выглядит именно так.
Если инициализация графического контроллера прошла успешно, то в регистре REG_ID графического контроллера устанавливается значение 0x7C. После проверки этого контрольного значения можно увеличить скорость SPI.

Последним подготовительным этапом является настройка параметров TFT-дисплея. Суть процедуры — запись в определенные регистры графического контроллера параметров конкретного TFT-дисплея. Мы один раз объясняем графическому контроллеру к какому именно дисплею он подключен, а потом используем универсальные библиотечные функции.

Что подразумевается под параметрами дисплея
Как перестать бояться и полюбить mbed [Часть 2] - 7

После настроек на дисплей выводится пустой экран. Далее, при необходимости, проводятся настройка сенсорного ввода и аудиоканала. Все эти процедуры многократно описаны производителем, поэтому, наверное, не нуждаются в пояснениях.

Вывод на дисплей графических примитивов и виджетов


После инициализации работа с дисплеем сводится к формированию очередного дисплей-листа и загрузке его на графический контроллер. Дисплей-лист — это список команд, в результате исполнения которых контроллер FTDI выводит на дисплей некое изображение.

Дисплей-лист начинается с записи в графический контроллер команды CMD_DLSTART и заканчивается записью команды DISPLAY(). Отображение дисплей-листа происходит по записи стандартного значения в регистр REG_DLSWAP.

В теле дисплей-листа может находиться до 2048 инструкций. Все они представляют собой простые команды вроде задания цвета объектов и отрисовки графических примитивов — линий, прямоугольников, точек и т.д.

Графический контроллер FTDI состоит из нескольких узлов, среди которых основной процессор, дополнительный графический сопроцессор, аудиосопроцессор и т.д. За выполнение простых команд дисплей-листа отвечает основной процессор FT800, однако микросхемы FTDI позволяют работать и с более сложными объектами — виджетами. Виджеты — это кнопки, слайдеры, шкалы, градиенты, текстовые строки, числа и так далее. Несмотря на то что отрисовка виджетов осуществляется сопроцессором, при формировании дисплей-листа можно вперемешку вызывать простые базовые функции и функции отрисовки виджетов.

Использование библиотеки FT800 в собственном mbed-проекте


В прошлой статье была подготовлена заготовка проекта — короткая программа, выводящая на виртуальный COM-порт счетчик секунд. Сегодня подключим к проекту библиотеку FT800 и будем выводить счетчик секунд уже на TFT-дисплей.

Среди mbed-разработчиков уже нашелся человек, имевший дело с графическим контроллером FT800. Этот самый человек, Peter Drescher, благополучно адаптировал для mbed библиотеку от FTDI, снабдил её примером использования и фотографиями. Спасибо, Peter!

Чтобы использовать библиотеку в своем проекте, кликаем на на Import library на посвященной FT800 странице, попадаем в свой компилятор и выбираем проект, к которому библиотека будет подключена. Разумеется, для всех этих телодвижений нужно предварительно зарегистрироваться на developer.mbed.org.

Как перестать бояться и полюбить mbed [Часть 2] - 8

Для использования библиотеки FT800 нужно подключить к своему main.cpp файл FT_Platform.h и объявить новый объект TFT класса FT800, также как мы объявляли объект pc класса Serial в программе из предыдущей статьи. Аргументами при объявлении объекта служат выводы платы, на которых доступны линии интерфейса SPI и сигналы PD и INT. Поскольку я буду запускать программу на трех разных платах, сразу расписываю распиновку для всех трех случаев:

#include "mbed.h"
#include "FT_Platform.h"

// SLSTK3400A
FT800 TFT (PE10, PE11, PE12, PE13, PB11, PD4); // mosi, miso, sck, ss, int, pd
// WIZwiki-W7500P
//FT800 TFT (D11, D12, D13, D10, D9, D8); // mosi, miso, sck, ss, int, pd
// ATSAMD21-XPRO
//FT800 TFT (PA18, PA16, PA19, PA17, PA20, PA21); // mosi, miso, sck, ss, int, pd

Сам конструктор класса FT800 лежит в файле FT_Gpu_Hal.cpp

FT800::FT800(PinName mosi, PinName miso, PinName sck, PinName ss, PinName intr, PinName pd):
	 _spi(mosi, miso, sck),
	 _ss(ss),
	 _pd(pd),
	 _f800_isr(InterruptIn(intr))
	 {
	 	 _spi.format(8,0);                  // 8 bit spi mode 0
	 	 _spi.frequency(2000000);           // start with 10 Mhz SPI clock
	 	 _ss = 1;                           // cs high
	 	 _pd = 1;                           // PD high
		 Bootup();
	 }

В конструктор класса FT800 уже включена вся процедура инициализации TFT-модуля — настройка интерфейса SPI и вызов функции Bootup(), которая описывает подачу 20-милисекундного импульса на линию PD, отправку нужной последовательности Host-команд, проверку REG_ID графического контроллера, дальнейшее задание частоты SPI в 20 МГц, а также настройка параметров TFT-дисплея.
Смотреть код можно здесь (листать в конец страницы).

Важно отметить, что дефайны для параметров TFT-дисплея задаются в файле FT_LCD_Type.h, где по умолчанию прописаны параметры дисплея стандарта WQVGA с разрешением 480 на 272.

Вы поймете что дисплей правильно подключен и корректно инициализирован, если после отработки конструктора загорелся белый экран, в любом другом случае нужно искать ошибку. Если же всё сделано правильно, можно начинать формировать первый дисплей-лист.

Приведу пример простой программы для вывода на экран счетчика секунд, круглых часов и ещё нескольких объектов.

Как перестать бояться и полюбить mbed [Часть 2] - 9
Единственный дисплей-лист будет состоять из следующих операций:

1. Начало дисплей-листа, установка белого цвета как цвета по умолчанию:

    TFT.DLstart();
    TFT.DL(CLEAR_COLOR_RGB(255, 255, 255));
    TFT.DL(CLEAR(1, 1, 1));

2. Установка черного цвета, вывод двух текстовых строк:

    TFT.DL(COLOR_RGB(0, 0, 0));
    TFT.Text(11, 15, 30, 0, "Demo-project for habrahabr.ru");
    TFT.Text(13, 15 + 40, 28, 0, "Using FT800 library");

3. Установка темно-зеленого цвета, вывод графического примитива «Прямоугольник»:

    TFT.DL(COLOR_RGB(9, 35, 5));
    TFT.DL(BEGIN(RECTS));
    TFT.DL(VERTEX2II(11, 105, 0, 0));
    TFT.DL(VERTEX2II(11 + 275, 105 + 100, 0, 0));

4. Установка белого цвета, вывод текста и числа секунд:

    TFT.DL(COLOR_RGB(255, 255, 255));
    TFT.Text(11 + 10, 105 + 10, 29, 0, "Number of seconds:");
    TFT.Number(11 + 10, 105 + 10 + 30, 31, 0, seconds);

5. Вывод одного из поддерживаемых на FT800 виджетов — часов:

    TFT.Clock(390, 105 + 70, 70, 0, 4, 20, (seconds % 60), 0);

6. Установка черного цвета, вывод текстовой строки:

    TFT.DL(COLOR_RGB(0, 0, 0));
    TFT.Text(11, 240, 28, 0, "e-mail: xk@efo.ru");

7. Вывод графического примитива «Прямая линия»:

    TFT.DL(BEGIN(LINES));
    TFT.DL(LINE_WIDTH(8));
    TFT.DL(VERTEX2II(11, 15 + 40 + 30, 0, 0));
    TFT.DL(VERTEX2II(460, 15 + 40 + 30, 0, 0));

8. Конец дисплей-листа, загрузка картинки на дисплей:

    TFT.DL(DISPLAY());
    TFT.Swap();

Обращаю внимание, что команды TFT.DL() — это описанные выше простые команды дисплей-листа, а команды TFT.Text(), TFT.Number() и TFT.Clock() — это инструкции сопроцессора.


Важно!
Для графических контроллеров серии FT800 в mbed доступно две библиотеки одного и того же автора — FT800 и FT800_2. Отличаются они друг от друга только названиями функций: в первой библиотеке используются те же названия, что в материалах от FTDI, а во второй все названия сокращены:

TFT.Ft_Gpu_CoCmd_Dlstart();
TFT.Ft_App_WrCoCmd_Buffer(CLEAR_COLOR_RGB(255, 255, 255));
TFT.Ft_App_WrCoCmd_Buffer(CLEAR(1, 1, 1));

TFT.Ft_App_WrCoCmd_Buffer(BEGIN(LINES));
TFT.Ft_App_WrCoCmd_Buffer(VERTEX2II(11, 15 + 40 + 30, 0, 0));
TFT.Ft_App_WrCoCmd_Buffer(VERTEX2II(460, 15 + 40 + 30, 0, 0));

TFT.Ft_App_WrCoCmd_Buffer(DISPLAY());
TFT.Ft_Gpu_CoCmd_Swap();

TFT.DLstart();
TFT.DL(CLEAR_COLOR_RGB(255, 255, 255));
TFT.DL(CLEAR(1, 1, 1));

TFT.DL(BEGIN(LINES));
TFT.DL(VERTEX2II(11, 15 + 40 + 30, 0, 0));
TFT.DL(VERTEX2II(460, 15 + 40 + 30, 0, 0));

TFT.DL(DISPLAY());
TFT.Swap();

Я использую второй вариант, однако у использования длинных названий функций есть неоспоримое преимущество: освоившись в таких именах вам будет гораздо легче использовать примеры от производителя и утилиты для автоматической генерации кода от FTDI.


Возвращаемся к примеру работы с дисплеем, программе для вывода счетчика секунд на TFT. За основу берем проект-заготовку из прошлой статьи, в котором с помощью базовой библиотеки mbed на последовательный интерфейс выводится счетчик секунд.

Вывод счетчика секунд на последовательный интерфейс
#include "mbed.h"

Serial              pc(USBTX, USBRX);
Ticker              timeKeeping;
volatile uint64_t     seconds = 0;

void secondsCallback(void) {
    pc.printf("Number of seconds: %xrn", seconds);
    seconds ++;
}
 
int main() {
    timeKeeping.attach(&secondsCallback, 1.0f);
    while(1) {}
}

Как перестать бояться и полюбить mbed [Часть 2] - 10

Вносим соответствующие изменения — подключаем библиотеку FT800, объявляем объект класса FT800 и вы бесконечном цикле вызываем функцию, формирующую описанный выше дисплей-лист.

#include "mbed.h"
#include "FT_Platform.h"

FT800 TFT (PE10, PE11, PE12, PE13, PB11, PD4); // mosi, miso, sck, ss, int, pd [SLSTK3400A]
//FT800 TFT (D11, D12, D13, D10, D9, D8); // mosi, miso, sck, ss, int, pd [WIZwiki-W7500P]
//FT800 TFT (PA18, PA16, PA19, PA17, PA20, PA21); // mosi, miso, sck, ss, int, pd [ATSAMD21-XPRO]

Ticker              timeKeeping;
volatile uint64_t     seconds = 0;

/***********************************************************************************************************************/
void secondsCallback(void)
{
    seconds ++;
}
 
/***********************************************************************************************************************/
/* Construct the screen and downloasd it to the TFT */
void drawTimeScreen(void)
{
    TFT.DLstart();
    TFT.DL(CLEAR_COLOR_RGB(255, 255, 255));
    TFT.DL(CLEAR(1, 1, 1));
 
    TFT.DL(COLOR_RGB(0, 0, 0));
    TFT.Text(11, 15, 30, 0, "Demo-project for habrahabr.ru");
    TFT.Text(13, 15 + 40, 28, 0, "Using FT800 library");
 
    TFT.DL(COLOR_RGB(9, 35, 5));
    TFT.DL(BEGIN(RECTS));
    TFT.DL(VERTEX2II(11, 105, 0, 0));
    TFT.DL(VERTEX2II(11 + 275, 105 + 100, 0, 0));
 
    TFT.DL(COLOR_RGB(255, 255, 255));
    TFT.Text(11 + 10, 105 + 10, 29, 0, "Number of seconds:");
    TFT.Number(11 + 10, 105 + 10 + 30, 31, 0, seconds);
    
    TFT.Clock(390, 105 + 70, 70, 0, 4, 20, (seconds % 60), 0);
    
    TFT.DL(COLOR_RGB(0, 0, 0));
    TFT.Text(11, 240, 28, 0, "e-mail: xk@efo.ru");
    
    TFT.DL(BEGIN(LINES));
    TFT.DL(LINE_WIDTH(8));
    TFT.DL(VERTEX2II(11, 15 + 40 + 30, 0, 0));
    TFT.DL(VERTEX2II(460, 15 + 40 + 30, 0, 0));
    
    TFT.DL(DISPLAY());
    TFT.Swap();
}
 
/***********************************************************************************************************************/
int main()
{
    timeKeeping.attach(&secondsCallback, 1.0f);
    while(1) {
        drawTimeScreen();
    }
}

Проект доступен по ссылке.

Чтобы получить файл прошивки для трех разных отладочных плат нужно, как и в прошлый раз, изменить целевую платформу в правом верхнем углу окна компилятора, а также изменить названия линий ввода-вывода. Вуаля — программа компилируется и работает на всех трех платах.

Как перестать бояться и полюбить mbed [Часть 2] - 11

В следующей статье будет описан процесс создания и подключения к нашему проекту библиотеки для датчика температуры и относительной влажности HYT-271. Будем потихоньку приближаться к полноценному приложению, работа которого продемонстрирована на видео.

Заключение


В заключении традиционно благодарю читателя за внимание и напоминаю, что вопросы по применению продукции, о которой мы пишем на хабре, можно также задавать на email, указанный в моем профиле.

Автор: ЭФО

Источник

Поделиться новостью

* - обязательные к заполнению поля