FT812. Архитектура



В этой статье я расскажу об особенностях работы и внутреннем строении FT812 с точки зрения разработчика подобных видеосистем.
Вопросы программирования сабжа будут рассмотрены поверхностно (а подробно — в отдельной статье).

Семейство чипов FT8xx имеет общее название: EVE (Embedded Video Engine). Прочитать описание возможностей от производителя можно здесь и здесь.

Данные видеопроцессоры позиционируются, как дешёвые решения для обслуживания экранчиков с тачскринами, например в пунктах продаж, для индикации режимов оборудования и тд.
Меня они интересуют, как крайне удобный видеоконтроллер для олдскульных восьмибитных развлечений.
Функционала тачскрина я намеренно не буду касаться, поскольку для нашей задачи он не требуется.

Из линейки FT81x я выбрал FT812, потому что эта разновидность поддерживает 24-битный цвет (а не 18, как FT810). Формат поддерживаемого тачскрина в нашем случае не имеет значения, поэтому FT813 тоже бы подошёл.

Можно заявить, что FT812 подключается к любому спектруму, но на самом деле не к любому. В минимуме требуется SPI интерфейс, например такой, как на Z-Controller. И тогда — да, к любому.

Итак, внутреннее устройство FT812.
Чип содержит:
— SPI интерфейс для коммуникации с хостом. По нему можно читать/писать память и регистры EVE и посылать команды.
— Пиксельный интерфейс, пригодный для подключения к видеоЦАП-у с VGA или HDMI выхлопом.
— Графический процессор.
— Память объёмом 1 мегабайт для хранения битмапов, звуковых сэмплов, фифо и других нужд.
— Память дисплей листа с двойной буферизацией.
— Регистры.
— Сопроцессор с собственным ПЗУ и говнокодами в нём для выполнения типичных задач, типа рисования градиентов.
— Аудиохрипелка с поддержкой ADPCM и моно выходом.
— PLL для генерации внутренней тактовой частоты.

Графический процессор EVE устроен по принципу дисплей листа.

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

Для графического процессора всё выглядит несколько по-другому.
Каждую видеостроку дисплей лист начинает обрабатываться с начала. В результате выполнения комманд из дисплей листа генерируется пиксельный буфер, который будет отображаться в течение следующей строки.
Каждая команда рисует только ту часть изображения, которая попадает в данную видеостроку. Скажем, если рисуется круг, то в буфер попадёт линия, начинающаяся с левого края круга для данной строки и заканчивающаяся справа.
Буферов два, они переключаются. Один отображается, второй строится.
Это хорошо заметно, если создать дисплей лист без команды очистки экрана. Сразу после включения память буферов содержит случайные значения, и видно, что два набора мусора повторяются через строку.

Дисплей лист поддерживает команды JUMP и CALL/RET со стеком глубиной 4. К сожалению, циклы и переменные не поддерживаются =)

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

Максимальное разрешение, заявленное для EVE — 800х600 пикселей. Оно должно напрямую задавать размер памяти пиксельного буфера — 800 пикселей. На самом деле, ко всеобщему счастью наконец наступили времена дешёвой памяти (даже, когда эта память — SRAM), поэтому, память буфера даже не 1024 пикселя, а я подозреваю, что 2048. По крайней мере, 1280 пикселей по горизонтали отображаются. Следовательно, заявленное разрешение — не предел.

Предел разрешения, выдаваемого EVE обусловлен максимальной частотой, на которой может работать графический процессор. Штатная частота 60МГц оверклочится, однако оверклок весьма ограничен. Девайс стабильно работает на 72МГц, но уже на 80 начинаются мелкие глитчи. Обидно, что есть делитель частоты для пикселей, относительно частоты PLL, а делителя для ядра нет. Поэтому нарисовать 1280х1024 с частотой пикселей 108МГц не получится. Можно попытаться вывести режим 1280х1024 с частотой пикселей 1/2, т.е. 54МГц, но профиту в этом особого нету. Разве что для получения более квадратных пикселей на мониторах с этим нативным разрешением.

Наиболее приемлимыми видеорежимами я считаю два:
— 800х600, 60Гц, частота ядра 40 или 80МГц,
— 1024х768, 60Гц, частота ядра 64МГц.
Чем ниже частота ядра, тем меньше объектов дисплей листа может обработать графический процессор за строку.

Вообще, скорость нарезки пикселей впечатляет. Для самого простого случая это 16 за такт. Для самого сложного (битмап с линейной фильтрацией) — 2. Это значит, что в дисплей лист можно набросать тонну слоёв, битмапов и всё это будет успевать отображаться.

Кстати об архитектурах.
TSU в TS-Conf работает примерно по тому же принципу, что и EVE. Однако есть различия.
Если для отображения дисплей листа не хватит тактов в строке, TSU в начале новой строки принудительно сбрасывается. В результате получится изображение без самых верхних слоёв, которое однако же будет ровным. В EVE принудительного сброса не происходит. Поэтому рисование буфера будет продолжаться до победного конца, в результате чего картинку перекосит.
Еще одно различие в том, что TSU принудительно чистит пиксельный буфер (параллельно с чтением из него), а в EVE требуется команда очистки, которая длится примерно 1/20 времени строки. Однако, очистку можно делать указанным цветом и альфой.

Рисование графических примитивов происходит с точностью 1/16 пикселя. Точность в данном случае касается координат и радиусов.
В реальном изображении такая точность передаётся через антиалайсинг.
Достигается эта точность путём подсчёта виртуальных пикселей в пространстве «1/16», где на каждый реальный пиксель изображения попадает 256 виртуальных пикселей графического примитива. Результат подсчёта помещается в альфу и смешивается с буфером по указанному правилу.
Для битмапов указанный приём к сожалению не работает.

Можно поразмышлять о внутреннем устройстве чипа.
Например, шина пиксельного буфера должна быть:
— 24 бита цвета,
— 8 бит альфы,
— 8 бит стенсила,
— 8 бит тэга,
— множим это все на 16 пикселей за такт,
— множим на 2, потому что чтение и запись идёт по раздельным шинам,
— 1536 бит!
Авторы видеокарт на бюджетных FPGA сейчас загрустили и убились апстенку =)

О сопроцессоре.
К сожалению, встроенный фирмварь у FTDI оставляет желать лучшего, что видно на примере Vinculum. В случае FT812 прошивка сопроцессора тоже несколько странная и работает со средней стабильностью.

Сопроцессор оборудован 4кБ фифо команд. По мере их выполнения фифо освобождается для новых.

Результатом выполнения большинства команд является наполнение дисплей листа. Иногда, результат выполнения — это распакованный JPEG, PNG или ZLIB.
Хранить данные, сжатыми в ZLIB, вполне удобно.

Еще сопроцессор умеет играть AVI файлы со звуком, где видеопоток упакован в MJPEG, что наводит на мысль, об аппаратном распаковщике JPEG битстрима.

Писать собственные коды на асме сопроцессора нельзя.

В плане распаковки ZLIB меня очень порадовало полное отсутствие в документации упоминание того факта, что PNG для распаковки требует 40кБ ОЗУ. И это ОЗУ не внутреннее, сопроцессора, а вполне себе обычное, в последних адресах 1МБ общего ОЗУ.
Если не знать об этом факте, то можно расположить в тех адресах, скажем, фифо данных и хорошенько завесить сопр, что и было проделано опытным способом.

О PLL.
В чипе имеется встроенный генератор на RC-цепочке, который хотелось задействовать вместо кварца. В последний момент я решил всё же поставить кварц, и правильно сделал.
RC действительно генерит клок, полезный для запуска устройства, но более ни на что не годящийся. В целях эксперимента можно запустить видео с RC, однако, это зрелище не для слабонервных. =)
Чувствительность изменения частоты RC-генератора от напряжения столь высока, что он будет чувствовать мобилку в соседней комнате и дёргать изображение соответственно.
С кварцем же картинка стоит идеально ровно. Слава кварцам!
  • avatar
  • [просмотров: 4182]
  • +31

5 комментариев

avatar
Возможности настолько крутые, что даже страшно пробовать :)
avatar
Ну как крутые… Просто видеочип здорового человека в 2017 году =)
avatar
Ну наконец-то становится понятно что оно, и с чем его есть)
  • VBI
  • 0
avatar
В дисплейлистах есть CALL/RET, а это значит что они могут быть древовидные.
Отсюда, не обязательно формировать весь дисплейлист заново, достаточно патчить в основном дисплейлисте команды CALL, подключая уже готовые дисплейлисты. Немного неясно, матрицы относятся только к битмэпам, или нет. Если матрицы способны двигать всё, то в начале дисплейлиста можно располагать матрицу и, таким образом, получать сложные иерархические трансформации сцены, с которыми легко справится Z80.
Profit!
avatar
Да, большое спасибо, я напрочь забыл про CALL/RET/JUMP! Добавлю в текст. На самом деле, я и собирался их использовать. Кроме них есть ещё другие приёмы. Стек графического контекста, например.

Матрицы относятся только к битмапам, они и называются BitmapTransformХ.

Есть ещё команда трансляции, проще говоря — Х и У скроллка для всех последующих объектов. Фактически, можно получать «неограниченное» количество пиксельных (и не только) плоскостей с индивидуальными «регистрами сдвига».
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.