Что есть жизнь? Это вечное стремление познавать не познанное. Я же познаю  программирование ПЛИС (программируемая логическая интегральная схема). Просто поморгать светодиодом для меня не очень интересно и пришлось придумать задачу серьезнее. Так и родилась идея видеокарты (VGA) для микроконтроллера. Серьезным дядькам эта штука вряд ли пригодиться, а вот новичкам... Очень даже может быть. От того и было решено «заточить» видеокарту под Arduino NANO.

Основой проекта стала ПЛИС EPM240T100C5N семейства MAX II. И понеслось: datasheet на микросхему, разводка печатной платы, заказ платы, ну и пайка. Такую мелочь я ещё не паял, но глаза боятся – а руки делают.  Так и родилось это устройство.

вид сверху
вид сверху
вид снизу
вид снизу

Подключаем Arduino NANO

Получаем на выходе 256 пикселей по горизонтали, 128 пикселей по вертикали и 256 цветов.

Демонстрационное видео.

Если есть  видеокарта, то, что мешает сделать видеоигру?  Сказано – сделано!

Картина была бы не полной без компьютерной мыши.)

Недостатки:

1. Низкое разрешение, но если учесть, что видеокарта рассчитана на низко производительный микроконтроллер, то это не недостаток, а продиктованная необходимость.

2. Задействовано слишком много пинов микроконтроллера. 8 – шина, 3-команды, 1- ответ от видеокарты.

 Вот такой вот мой первый блин. А съедобен он или нет решать Вам!

Комментарии (57)


  1. Ivanii
    07.10.2021 19:13

    Какова скорость передачи по шине?


    1. PNP80 Автор
      07.10.2021 19:34
      +2

      Видеокарта готова принять за 1 такт координату Х, 1 такт координату Y и 4 такта цвет с последующим сохранением в ОЗУ.  Установлен кварц 50 МГц. Получается более 8 миллионов пикселей в секунду. Но это теоретически.)


      1. Ivanii
        07.10.2021 20:44

        Я про реальную требующуюся, у меня SPI на соплях из пинов дает 4 Мбит/с, работает аппаратно на меге и занимает 5 пинов.


        1. yatanai
          09.10.2021 02:10

          Я могу ошибаться, но пины ардуинки могут меняться на частоте мк. То есть, при 12МГц у нас макс скорость будет примерно 4МТ\с, если учесть что команды по 1 такту. (Load->Store->Inc(void* picture))
          Тоесть для 256х198 мы можем передавать в 60фпс. (для коня в вакууме)

          А учитывая его кривущую архитектуру, там дай бог 10фпс выжать. (в видео слайдшоу, какб)
          @PNP80Зачем передавать позицию знакоместа? Для передачи пикселей можно было просто сделать FIFO буфер и вывести пин "FIFO на половину пуст" и добавить пару команд для синхронизации. Это бл тупо удобнее, у тебя в коде просто привязка позиции пикселя и фиговина дёргает прерывание и ты просто кидаешь туда данные. Всё, ничо даже рисовать не надо, ты тратишь минимум тактов мк на отрисовку и при более мощных мк этим будет заниматься DMA. пффф
          +Если ты косишь под "ретро" то тем более кринж, 1 передача = 1 пиксель. (при 8битной шине) Если хочется много цветов, то 16бит твой предел. Почему 4 такта на пиксель??? У тебя там синхронизации какие-то? Я не могу понять...пфффф
          Не был бы я нищим, я бы "показал как надо", ахахах


          1. yatanai
            09.10.2021 03:25

            @PNP80 Внизу скинули ссылку на этот проект. И это кринжатина лютая.
            Ты дёргаешь пины по отдельности, серьёзно? А почему нельзя по маске писать?
            Я кнш не вкурсе как там AVR устроена, но вроде под выводы у неё просто кусок памяти, где прописано направление данных и сами регистры с этими данными.
            ***
            Тоесть у тебя в идеале должно уходить всего 4 команды, при твоей разводке, на выставление данных на шине. + "ПЛИС" у тебя детектирует данные по фронту? Это ещё +2 команды, ибо AVR вроде умеет в битовые команды с памятью.
            Итого, в идеале у тебя выходит 6 команд на одну передачу по шине, если учесть что команда = 1 такт, то предел по шине около 2МТ\с при 12МГц. (или 8 команд для данные + команды ПЛИС, итого ~1МТ\с)
            А у тебя просто вырезки из либ где ты по одному пину ставишь...
            ***
            Я так же не понимаю почему ты не сделал просто клок + команды. Это же вроде самое первое что лезет в голову если ты хоть немного знаком со схемотехникой и как работают шины те жы RAM,PCI,ISA в компах. У тебя тупо на 1 команду больше будет, даже при текущей "архитектуре". То есть, 1 детектор 2 регистра (8х2) там в лучшем случаее 14 ячеек на это уйдёт (если они организованы как LUTх3+Регистр).
            ***
            + Ок, в MAX2 240 нету sram, тут мой косяк. Так сказать - "Прошу прощения, зря быканул". FIFO нормальное не сделать, максимум должно на 8-12 записей хватать. Хотя там есть флеш на 1КБ...
            Я в замешательстве) Как ты данные синхронизируешь, да и ещё пишешь "по пикселю"? Поведаешь нам?


            1. COKPOWEHEU
              09.10.2021 10:40
              +1

              Ты дёргаешь пины по отдельности, серьёзно?
              Тоже посмотрел исходники. Похоже, ардуинщики не в курсе что такое DDR, PORT, PIN и что digitalWrite в 30 раз медленнее обычной работы с портами. Не говоря о такой чуши, как куча digitalWrite подряд.
              А десятком строк ниже уже PORTD |= (1<<2); //digitalWrite (2, HIGH);
              Определитесь уже в каком формате пишете!


              1. PNP80 Автор
                09.10.2021 13:34

                Я художник - я так вижу.)))


            1. PNP80 Автор
              09.10.2021 13:32

              Требовать с любителя как с профессионала – не профессионально!)))

               Видеокарта берет содержимое ОЗУ и прорисовывает на мониторе, потом сообщает микроконтроллеру о готовности принимать данные (можно конечно в любое время передавать данные, но будут артефакты на мониторе), камень передает координаты пикселя и цвет.

              Если отказаться от  координат, значит, контроллеру придется передавать полностью страницу. А страница весит 32 КБ.


              1. COKPOWEHEU
                09.10.2021 15:36
                +1

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

                Если отказаться от координат, значит, контроллеру придется передавать полностью страницу.
                Разумеется, нет. Потому что см.выше.
                Попробуйте поработать с тем же ili9341, про который я уже писал. Один из самых распространенных дисплеев ведь.


                1. PNP80 Автор
                  09.10.2021 15:50

                  Скажем, в SPI-дисплеях можно и область вывода указать, если нужно вывести не всю картинку, а только небольшой прямоугольник

                  Отличная идея! Спасибо за совет!


              1. yatanai
                10.10.2021 03:19

                Тут выше уже отписали. Но суть в том что ты можешь много чего поставить на конвейер. Банально выдав команду "поменять режим" и передав его через 8бит шину. А потом так же настроить х,у и слать данные просто дёргая пин "клока", внутри там просто инкрементный счётчик + мультиплексор от текущего стейта. Это делается очень легко и ресурсов не много тратит, должно в MAX2 эту помещаться.
                Тоесть даже не переделывая код железки у тебя выйдет 1 пин для "клока" и 2 пина на 4 команды типа - "выставить х", "выставить у", "передать данные", "поменять режим"
                А там на стейт машинах можно почти шо угодно сделать, даже то же рисование куска экрана, просто ещё 2 регистра с координатами, доп проверка на переполнение и 2 битный регистр на состояние (надо же границы рисуемого квадрата передать, а потом рисовать).
                Ещё немного наговнокодить и можно даже SDRAM буфер на прямое чтение передавать, но это уже просто приколы)


                1. PNP80 Автор
                  11.10.2021 17:34

                  У меня есть одна проблема: ресурс  используемой ПЛИС  очень ограничен, поэтому в этом варианте это все будет не возможно.


                  1. yatanai
                    19.10.2021 08:58

                    Чел, угараешь? У тебя какая утилизация кристала? Всмсл, сколько ячеек занимает?

                    ***Так, чего-то я напутал, ночью фигню написал, там вся эта магия с пакетной\указатель модами должна +-40 ячеек сожрать.
                    (Закраска Области и Пакетный режим по сути работают одинаково, потому смысла их отделять нет)
                    А чтение можно прикрутить условно бесплатно или ценой 1 мультиплексора на шину адреса VGA->SDRAM, хотя двунаправленные выводы могут чуть больше ячеек сожрать, тут хз


      1. rPman
        08.10.2021 09:21
        +2

        Попиксельное рисование пока единственное что умеет видеокарта?
        Рисование примитивов и спрайты были бы уместны, мне кажется.

        p.s. я понимаю что это ради само образования проект
        а так, по стоимости результат мягко говоря грустный, плисины не дешевые и вообще оверкил


  1. VT100
    07.10.2021 19:14
    +6

    Из зала кричат: "Слайды!"

    Т.е. немного о преодолении трудностей и ссылки на коды и схемы.


    1. PNP80 Автор
      07.10.2021 19:43

      если на скорую руку, то можно глянуть схему и исходники здесь(правда чуть чуть устаревший вариант. Нет функции "пипетка")

      https://hackaday.io/project/179852-bk-1-vga-board 


  1. Alyoshka1976
    07.10.2021 19:23

    del


    1. PNP80 Автор
      07.10.2021 19:45

      К сожалению  нет. Первый опыт – не возможно все предусмотреть.


  1. 4e1ovek
    07.10.2021 20:37

    ESP прикрутить и дашборды выводить.


    1. praeivis
      08.10.2021 14:23

      Так прикрутили давно уже: https://www.youtube.com/watch?v=wu5sySCW5NE


  1. trak
    07.10.2021 22:56

    "Вы вообще нормальный?!" :) На самом деле уважаю, сам никогда такое не повторю, к сожалению.


    1. dcoder_mm
      07.10.2021 23:15
      +11

      А у вас же там нет фреймбуфера и тайминги шины завязаны на тайминги VGA? Зачем тогда передавать координаты пикселей?

      И если нет фреймбуфера, то зачем вообще ПЛИС, можно дергать пинами с таймингами VGA: Раз, Два, Видеоигры
      И даже на сайте хабрахабр точка ру

      P.S. Это должен был быть коммент к статье, а не реплай. Я не очень умный.


  1. Fasterpast
    08.10.2021 01:32
    +1

    Любопытно ) Можно ведь сделать аппаратный скроллинг и поддержку спрайтов, тогда и Марио будет плавно работать.


    1. alexzeed
      08.10.2021 13:11
      +1

      Это уже не просто видеокарта, а целый GPU получится!


  1. Hasan81
    08.10.2021 08:31

    Вы молодец! Запускайте в продажу и не слушайте завистников!


  1. qixiz
    08.10.2021 09:30
    +2

    Здорово! Завидую!) Связка ПЛИС + Arduino выглядит как неравный брак. Насколько просторнее надо взять ПЛИС, чтобы одновременно эмулировать Arduino?


    1. PNP80 Автор
      09.10.2021 14:34

      Затрудняюсь ответить на Ваш вопрос.


    1. yatanai
      10.10.2021 05:39

      Я точно не помню, но есть проекты мегх каких-то, у них утилизация на ~2-5К ячеек, притом они полностью совместимы с последними стандартами AVR. Есть ещё проекты на OpenCores, но там самопал какой-то, я не смотрел. Так же есть сайт marsohod.org вроде, там дядьки делают самоделки, там же делали "микро AVR" на том же камне что и у нашего героя. Единственное на марсоходе деды сидят которые в схем-редакторе рисуют прошивку, verilog\VHDL кода там мало.
      На счёт нормальных ядер AVR под "ПЛИС", там у вас говнокодить не выйдет. Это нормальные люди пишут с нормальными инструментами и скорее всего у вас даже с "разгона" на обкуривание док ничего не получиться. Максимум на шину устройство своё прикрутить, не более. (грубо говоря сделать свой AVR с 8 SPI+UART, ок?)
      ***
      Из более менее обкатанного даже на марсаходе - amber ARM v2. Железка неплохая, код хоть и перегруженный названиями, но разобраться можно. Утилизация около 1.5-2К, если правильно помню. На этой фигне чо только не делали, можно много нагуглить, я полагаю. (+он там вроде по wishbone шине работает, тоесть просто взять что-то из opencores и прикрутить туда не сильно проблем создаст)
      ***
      Если совсем скучно, можно попробовать написать самописный процессор, это не сложно. Из минусов - придётся писать прогу для ассемблера. + Надо отладчиком научиться пользоваться, чтоб хернёй не страдать. (как я раньше) Будет у вас процессор читать из порта SPI, а данных там нет, почему? (пример)
      ***
      Итого вам должно хватить 6К ячеек "ПЛИС" для всяких маленьких подделок с софт процом, а хотите что-то нормальное, берите хотя бы 20К. (хотя что "самодельщик" может тяжёлого сделать? лол)
      ЗЫ Если сами разводите платы берите CPLD, ибо в FPGA нужна флеш для прошивки, а там легко накосячить и не то взять если детально не разобраться. (хотя CPLD быстро умирают если напряжения и эксплуатационные условия не соблюдать, но что вам эти +- пол года на утечку 1 бита из прошивки?)


  1. COKPOWEHEU
    08.10.2021 11:36
    +14

    А где статья-то? Какую полезную информацию можно получить из набора картинок и видео? Где описание работы, подводные камни, ограничения — где хоть что-то?!


    1. dlinyj
      08.10.2021 12:50
      +1

      Я не автор, если что. Но вот hackaday.io/project/179852-bk-1-vga-board

      А по теме, такое чаще всего, когда есть законченное изделие, поделиться его работой хочется, а детально рассказать уже не хватает моральных сил.


      1. COKPOWEHEU
        08.10.2021 13:31
        +4

        Эта ссылка должна быть в «статье».
        Ну а еще нормальные статьи принято начинать с постановки задачи: для чего это вообще делалось. Мне, например, не очевидно, насколько хватит возможностей Ардуины, учитывая, что у нее всего 4 кБ оперативки.


        1. dlinyj
          08.10.2021 14:01

          Я всецело разделяю ваше негодование.


        1. Alyoshka1976
          08.10.2021 15:31

          Оперативку можно расширять посредством I2C или SPI модулей. Тогда одной Arduino Nano (ака ATmega 328) хватает для косплея автономного 8-битного компьютера под управлением CP/M с выводом текстового изображения на ТВ 20 строк по 45 колонок символами 4x8, PS/2 клавитура поддерживается примкнувшим STM8. А в плане видеокарт - одна выделенная Arduino Nano может выводить монохром 320x224 с аппаратным плавным попиксельным вертикальным скроллингом (это реализуется очень просто - смещением адреса начала видеобуфера, такую штуку использовали в стародавние времена в одном из Amstrad-ов).
          P.S. А можно обойтись и без дополнительной оперативки - память можно эмулировать SD-карточкой, с кэшированием командная строка CP/M вполне отзывчива - такое тоже было, в еще более древних машинах, память на магнитных барабанах играла роль ОЗУ.


          1. COKPOWEHEU
            08.10.2021 15:53
            +1

            Оперативку можно расширять посредством I2C или SPI модулей.
            Только скорость тогда вообще в ноль упадет. Даже в идеальном случае на чтение 1 байта уйдет 16 тактов. Не считая адреса и работы драйвера этой внешней ОЗУ.
            с выводом текстового изображения
            Вот вывод текста это другое дело. Если не рисовать каждую букву из пикселей, а послать видеокарте команду «нарисуй 'A'».
            А в плане видеокарт — одна выделенная Arduino Nano может выводить
            ИМХО практичнее было бы сэмулировать какой-нибудь дисплей, который к ардуинам подключают — ili9341 например — и выводить не на трехдюймовую матрицу, а на VGA. По крайней мере под них уже написано довольно много кода, глядишь и пригодится кому.
            А если бы такое делал я, скорее ориентировался бы на терминалы вроде vt100 — с управлением по UART. Ну, может, добавил бы специфичных ESC-последовательностей для графического режима.


            1. Alyoshka1976
              08.10.2021 16:07

              Только скорость тогда вообще в ноль упадет. Даже в идеальном случае на чтение 1 байта уйдет 16 тактов. Не считая адреса и работы драйвера этой внешней ОЗУ.

              Все верно - но штатная оперативка атмеги используется как кэш - однолинейный для инструкций, многолинейный - для данных (все по настоящему )))). И еще немаловажно - атмега еще и эмулирует 8080-й. Скорость эквивалентна 500-600 кГц 8080-го в FAST-режиме (когда гасится экран), 150 кГц - в обычном - медленно, но командная строка CP/M вполне-вполне отзывчива.

              Вот вывод текста это другое дело. Если не рисовать каждую букву из пикселей, а послать видеокарте команду «нарисуй 'A'».

              Совершенно верно. Во флэше атмеги прошит знакогенератор, экранный буфер в памяти меги - символьный, эмуляция BIOS-процедур CPM 2.2 - экранные - там все просто, а вот разобраться с форматом данных для дисковых процедур - не совсем). IMHO получается симпатично (это знаменитый в узких кругах тест процессора, пройденный "нанокомпьютером"):

              выводить не на трехдюймовую матрицу, а на VGA

              Вывод на телевизор (композитный сигнал).

              P.S. Поддерживаются два виртуальных экрана (буква L в строе статуса обозначает левый экран) (аналогичная штука было в многих микрокомпьютерах, например, Osborne), поэтому чтобы посмотреть правую часть - надо переключиться нажатием сочетания клавиш на PS/2-клавиатуре). Получился полный фьюжн из разных техник, примененных в компьютерах времени моего детства.
              P.P.S. Небольшой чит - экран снят ТВ-тюнером, а не фотографированием телевизора.


              1. COKPOWEHEU
                08.10.2021 22:39

                Куда-то вас слишком далеко занесло. У AVR и так с мощностью негусто. Чего вы хотите добиться, заставляя ее еще и эмулировать другой процессор?


              1. Rigidus
                09.10.2021 04:06

                Хотелось бы повторить такое. Есть ли статья/схемы/руководство?


          1. dcoder_mm
            08.10.2021 18:30

            А можно взять более жирный МК, у которого наружу торчит параллельная шина (большие AVR/STM32) и повесить на нее и внешнюю память и видеокарту. Будет всё как у больших компьютеров


  1. dlinyj
    08.10.2021 12:23

    Потрясающая работа! А вы платы сами не продаёте для народа?


    1. PNP80 Автор
      09.10.2021 15:26

      Серийного производства нет.  Но если будут заказы, то несколько штук могу спаять.


  1. pdragon
    08.10.2021 16:37

    Где купить?


  1. seri0shka
    08.10.2021 21:48

    Ничего себе уровень для новичка!

    Предположил, что EPM240T100C5N стоит раз в пять дороже Arduino NANO. Посмотрел, оказалось гораздо привлекательней (с поправкой на нынешние цены контроллеров). Есть ли какая ардуиноподобная среда, чтоб попробовать "войти" в ПЛИС?


    1. Ivanii
      08.10.2021 22:55

      Есть Квартус с графическим редактором.


      1. SignallerK
        09.10.2021 10:32

        К сожалению, в графическом редакторе вот только такие схемки и можно делать. Всё что сложнее Verilog /VHDL.

        Это не в смысле, что он плохой, а просто код потом удобнее поддерживать, чем разбираться в паутине связей.


        1. Ivanii
          09.10.2021 18:12

          Мне не хватило 240 LE в таком проекте, иерархию никто не отменял и разговор про начало, а не профессиональную разработку на 10 - 100 тысяч LE.


        1. yatanai
          10.10.2021 05:47

          Там можно наловчиться разбираться в схемах + там так же поддерживаются все эти фичи с разбиением схем на модули. + даже пару вич есть типо табличных значений или памяти. (не помню точно, ибо тоже не пользуюсь этим)
          С другой стороны описывая код на Verilog/VHDL придётся иногда смотреть чо оно там на генерировало, а так ты сразу видишь схему перед глазами. Так что тут дело вкуса кто на чём схемы описывает.


    1. PNP80 Автор
      09.10.2021 15:34

      я делал в Quartus поведение описывал на Verilog


  1. andreimuvila
    09.10.2021 12:49
    +1

    Осталось только портировать Doom на Arduino))


    1. usa_habro_user
      09.10.2021 19:40
      +1

      "Сто лет в обед" как: https://www.esp32.com/viewtopic.php?f=18&t=2338 и еще куча подобных проектов.


  1. AaRoN_2021
    09.10.2021 12:49

    Вопрос а стоит ли покупать и использовать или лучше покупать какую-то другую видео карту?


    1. COKPOWEHEU
      09.10.2021 15:40
      +1

      Для AVR смысла в видеокарте немного. У нее не хватит ни памяти, ни скорости подготовить картинку. Ее потолок что-то вроде упоминавшихся ранее ili9341 с разрешением 320х240. Естественно, о быстром обновлении, красивых анимациях и прочем речь и близко не идет. Максимум можно загрузить фоновую картинку с внешней флешки и рисовать поверх нее буковки и циферки.


      1. yatanai
        10.10.2021 05:55

        Проще сравнить это всё с ~8086 и задаться вопросом - "А что те системы умели в плане графики".


        1. COKPOWEHEU
          10.10.2021 11:46

          Те системы имели несколько больше оперативки. Да и вообще были больше заточены на общение с человеком, чем с другими железками.


          1. yatanai
            10.10.2021 19:51

            Там скорее просто прикол, что цпу наружу торчал шиной ОЗУ, от чего налепить туда любой обвяз было не проблема. И так же к шине крепилась фигня которая тебе буквы на мониторе рисовала. Эх, это был буквально самый лучший конструктор на микрухах которой ты бы мог себе представить.
            А так в тех камнях 32-64КБ как раз уже был минимальный стандарт, примерно как в текущих жирных микрухах типо меги. Там сильно позже уже начали и 128КБ и 1МБ осваивать, ибо память тогда дорогая была. *К примеру - 8086 был выпущен в 1978 году, а популярные зхспеки у которых 16КБ-48КБ лишь 1982.


            1. COKPOWEHEU
              10.10.2021 21:51

              32-64кБ это оперативки, а в Мегах столько флеша. А оперативки там всего 4 кБ. Даже в stm-ках 32кБ ОЗУ далеко не всегда встретишь.

              Там скорее просто прикол, что цпу наружу торчал шиной ОЗУ
              Так линии для внешней памяти даже в древней AT90S8515 есть, не говоря про более свежие контроллеры. И дисплеи соответствующие встречаются.
              Вот только и требования к графике растут. Сейчас вряд ли кого можно впечатлить 4-цветной картинкой. Минимум Doom подавай.


  1. webdi
    12.10.2021 09:55

    Отлично получилось! Особенно для "первого блина".


  1. axe_chita
    12.10.2021 11:40

    Вроде бы на bluepill в монохроме до 800 на 600 разгонялись, и ЕМНИП поднимали текстовый терминал. осталось только графику поднять.
    Навскидку
    Видео-контроллер на ATmega32
    AVR, ARM, CPLD и VGA… 1760 часов чистого времени
    Игровая видеоконсоль на AVR AVGA
    stm32f103-vga-rs
    VGA output using a 36-pin STM32