- PVSM.RU - https://www.pvsm.ru -
Всем привет!
В одной из предыдущих статей [1] мой коллега Des333 [2] реализовал фреймбуфер для LCD, работающего на графическом контроллере ILI9341 [3]. Однако, его написание потребовало существенного опыта в разработке RTL-кода.
К тому же, не у каждого под рукой есть embedded LCD-дисплей, зато наверняка есть монитор с VGA-входом.Что же делать, если опыта разработки под FPGA мало, но есть SoC, а сделать что-то интересное хочется?
В этой статье мы расскажем, как разработать графический контроллер, имея на руках плату с SoC (Altera Cyclone V), дисплей с VGA и минимальные знания языков HDL (в нашем случае — Verilog).
Для примера будем использовать наши платки, но всё описанное заработает и на других.
Кому интересно, прошу под кат.
Я планирую рассказывать в следующем порядке:
Я буду использовать отладочную плату CB-CV-SOM [4], работающую вместе с SoDIMM-модулем CV-SE-SOM [5]:
К этой отладочной плате у нас есть шилд, на котором помимо VGA есть много интересного (см. metrotek.spb.ru/cbcvsom.html [4])
Для вывода изображения на дисплей нам нужны фреймбуффер [6], драйвер и модуль развёртки, который обеспечит связку между процессором и дисплеем, а также обеспечит непрерывное обновление кадров.
В SoC'е к ARM ( также называется HPS — Hard Processing System ) подключенна DDR3 память (1 GB в нашем случае), в ней и будет находится наш фреймбуффер. А в FPGA будет модуль, который нам нужно будет сделать с помощью Qsys.
Вот схема:
Работать все будет так:
VGA ( Video Graphics Array ) — это видео интерфейс, использующий аналоговый сигнал для передачи цветовой информации. Формат сигналов и их поведение похожи на тевелизионный сигнал.
Список сигналов:
vga_vs_o — вертикальная синхронизация
vga_hs_o — горизонтальная синхронизация
vga_r_o — данные красной составляющей пикселя
vga_g_o — данные зеленой составляющей пикселя
vga_b_o — данные синий составляющей пикселя
Shield поддерживает 16 бит на цвет, а это значит, что на синий и красный выделяется по 5 бит, а на зеленый 6. ЦАП сделан по схеме R2R.
У мониторов различные разрешения и частота обновления изображения. Эти параметры регулируются в VGA с помощью вертикальной и горизонтальной сихронизаций. У которых есть следующие параметры:
Времянки выглядят так:
Мы будем использовать режим VGA 800x600 на 60 Hz, cледовательно параметры следующие (параметры для других режимов [7]):
Тактовая частота 40 MHz
Горизонтальная синхронизация:
Вертикальная синхронизация:
Чтобы получить прошивку, нам в Qsys потребуются следующие модули:
Из процессора выходят AXI [8] интерфейсы H2F и F2H, у IP-ядер Альтеры интерфейсы Avalon-ST и Avalon-MM [9], поэтому нужен еще модуль межсоединения ( Interconnect ), который должен конвертировать из одного интерфейса в другой и мультиплексировать потоки данных. Он появится автоматически при генерации файлов.
Подробнее про Frame Reader и Clocked Video Output можно посмотреть тут [10].
Как собрать прошивку и какие настройки нужны для HPS можно прочитать в этой статье [11].
Настройки PLL.
Здесь настраиваются:
Параметры Bits per pixel per color plane и Number of color planes in parallel связаны с драйвером и объясняются ниже. Обратите внимание, что размерность интерфейса с HPS cовпадает с размерностью Master port width.
Здесь:
И теперь всё соединяем. Настройки для модуля Frame Reader «цепляем» к h2f master, интерфейс для передачи данных f2h slave. Соединяем Clocked Video Output с Frame Reader avalon_streaming_source -> din. Все тактируется outclk0.
И генерируем файлы, нажав Generate HDL ....
Как выше сказано, на плате 16 бит, а из модуля выходит 32 бита, поэтому нужно внимательно назначить пины в qsf-файле, либо отредактировать выход для себя удобным образом в top файле проекта. Нам нужны старшие биты каждого цвета, они более информативны, чем младшие.
Обратите внимание, что это первое и единственное место, где мы редактируем код. Больше это не потребуется.
logic vga_v_sync;
logic vga_h_sync;
logic [31:0] vga_data;
logic [7:0] vid_r;
logic [7:0] vid_g;
logic [7:0] vid_b;
assign vga_r_o = vid_r[7:3];
assign vga_g_o = vid_g[7:2];
assign vga_b_o = vid_b[7:3];
assign vga_hs_o = vga_h_sync;
assign vga_vs_o = vga_v_sync;
assign { vid_r, vid_g, vid_b } = vga_data;
Нам потребуется драйвер altvipfb [12].
Вернемся к параметрам Bits per pixel per color plane и Number of color planes in parallel в Frame Reader. В драйвере написано:
if (bits_per_color != 8) {
dev_err(&fbdev->pdev->dev,
"bits-per-color is set to %i. Curently only 8 is supported.",
bits_per_color);
return -ENODEV;
}
if (!(fbdev->mem_word_width >= 32 && fbdev->mem_word_width % 32 == 0)) {
dev_err(&fbdev->pdev->dev,
"mem-word-width is set to %i. must be >= 32 and multiple of 32.",
fbdev->mem_word_width);
return -ENODEV;
}
Число бит на один цвет только 8 и ширина слова должна быть больше или кратна 32. С чем же связано такое ограничение? Смотрим дальше и видим:
/* settings for 32bit pixels */
info->var.red.offset = 16;
info->var.red.length = 8;
info->var.red.msb_right = 0;
info->var.green.offset = 8;
info->var.green.length = 8;
info->var.green.msb_right = 0;
info->var.blue.offset = 0;
info->var.blue.length = 8;
info->var.blue.msb_right = 0;
Становится ясно, что драйвер работает в режиме True color, записывая цвет в 32 битное слово ( более удобно выравнивать, чем 24 ), и работает он только в таком режиме.
Чтобы собрать этот драйвер, в конфиге ядра надо внести следующие изменения.
CONFIG_FB_CFB_FILLRECT=m
CONFIG_FB_CFB_COPYAREA=m
CONFIG_FB_CFB_IMAGEBLIT=m
CONFIG_FB_ALTERA_VIP=m
Для того что бы linux узнал, что у нас в FPGA есть фреймбуфер от Альтеры, в dtb надо прописать следующие магические слова:
hps_0_h2f: bridge@0xc0000000 {
compatible = "altr,bridge-1.0", "simple-bus";
reg = < 0xc0000000 0x20000000 >;
#address-cells = < 1 >;
#size-cells = < 1 >;
ranges = <0x00000000 0xc0000000 0x4080 >;
alt_vip_vfr_1: vip2@0x0 {
compatible = "ALTR,vip-frame-reader-13.0", "ALTR,vip-frame-reader-9.1";
reg = < 0x4000 0x00000080 >;
max-width = < 800 >; /* MAX_IMAGE_WIDTH type NUMBER */
max-height = < 600 >; /* MAX_IMAGE_HEIGHT type NUMBER */
mem-word-width = < 0x80 >;
bits-per-color = < 0x8 >;
};
};
В параметре range — диапазон валидных адресов, с которых драйвер будет читать, а в reg = < 0x4000 0x00000080 > — стартовый адрес и сколько адресов занято alt_vip. mem-word-width это параметр Master port width в Frame Reader.
Подробнее про dtb [13].
Заходим на прибор и загружаем драйвера:
modprobe altvipfb
modprobe fbcon
Затем проверяем, все ли хорошо с помощью dmesg, и смотрим, есть ли похожая строка:
[ 66.424283] altvipfb c0000000.vip2: fb0: altvipfb frame buffer device at 0x2c000000+0x12c000
Ура! Появился fb0:
ls -l /dev/fb0
crw-rw---T 1 root fb 29, 0 Nov 26 10:13 /dev/fb0
Затем выводим консоль на экран, подключенный к плате:
/sbin/getty 38400 tty1
Ставим icewm [14] и запускаем с помощью startx:
apt-get install icewm icewm-themes
startx
Итого: мы получили графический контроллер, с минимальными знаниями HDL языков.
Автор: НТЦ Метротек
Источник [15]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/fpga/120277
Ссылки в тексте:
[1] одной из предыдущих статей: https://habrahabr.ru/company/metrotek/blog/263571/
[2] Des333: https://habrahabr.ru/users/des333/
[3] ILI9341: http://www.newhavendisplay.com/app_notes/ILI9341.pdf
[4] CB-CV-SOM: http://metrotek.spb.ru/cbcvsom.html
[5] CV-SE-SOM: http://metrotek.spb.ru/cyclonevsom.html
[6] фреймбуффер: https://ru.wikipedia.org/wiki/Linux_framebuffer
[7] параметры для других режимов: https://marsohod.org/projects/marsohod2/278-vhdlvga
[8] AXI: http://www.gstitt.ece.ufl.edu/courses/fall15/eel4720_5721/labs/refs/AXI4_specification.pdf
[9] Avalon-ST и Avalon-MM : http://www.altera.com/literature/manual/mnl_avalon_spec.pdf
[10] тут: https://www.altera.com/literature/ug/ug_vip.pdf
[11] статье: https://habrahabr.ru/company/metrotek/blog/235707/
[12] altvipfb: https://github.com/altera-opensource/linux-socfpga/blob/socfpga-3.18/drivers/video/fbdev/altvipfb.c
[13] dtb: https://habrahabr.ru/company/metrotek/blog/271983/
[14] icewm: https://ru.wikipedia.org/wiki/IceWM
[15] Источник: https://habrahabr.ru/post/282189/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.