Doom Boy ESP32

Приставка для Doom на ESP32 своими руками на драйвере MCP23017 для кнопок от UncleRus

e_br13t_nva7dv5lrbr8b9-8rpo.jpeg
it_4wjuhc9m8api63gzolghcwlq.jpeg

В ожидании Doom часов пришла плата давнего проекта. На плате разведено внешние MCP23017 и CS4344 и еще много чего

Для кнопок используется расширитель портов MCP23017 подключенный по I2C. Для него есть драйвер который можно взять у UncleRus. Сделана попытка запуска внешнего АЦП CS4344

Doom от Espressif


Скачав порт Дум пришлось немного повозится чтобы его собрать. В конечном итоге все собралось и залилиось в ESP32 но… я поймал крэш на старте. На githab Issue проекта увидел аналогичное обсуждение проблемы
vycpkjmc1qkwolkxdlxsvcutgqu.png
Автор порта предлагал сделать

You probably need to use the malloc () option as well as reserve some memory for DMA. I’ll see if I can get this compiling on master and update the sdkconfig when I have time.

В общем я «недолго думая» заменил все портированые функции выделения памяти на malloc ()
Демка запустилась. Впереди меня ждало подключение кнопок

MCP23017 GPIO extender


a8e0zxgbcoljjm4vgecqqft5pxm.png

MCP23017

С большими планами на расширения функционала посредством портов контроллера, решил немного сэкономить на портах ввода вывода самого микроконтроллера, поставив MCP23017. Это простой расширитель с доступом к сигналам ввода вывода через интерфейс I2C. Я не изобретал драйвер, а просто взял его у UncleRus. Пять кнопок использует джойстик для навигации. Пару кнопок на выстрел и выбор меню. На самом деле этого недостаточно, надо еще открывать двери и двигаться влево-вправо без поворота то есть как краб. Контакты подтянуты внутри MCP23017 к VDD. Контакт замыкается на землю. Очень круто что внутри микросхемы есть резисторы подтяжки. Можно было бы еще заморочится с прерываниями от MCP23017. В ней есть два вывода на каждый порт INTA и INTB, но как нибудь в другой раз.

Полный список команд
static const JsKeyMap keymap[]={
	{0x10, &key_up},
	{0x40, &key_down},
	{0x80, &key_left},
	{0x20, &key_right},
	
	{0x4000, &key_use},				//cross
	{0x2000, &key_fire},			//circle
	{0x2000, &key_menu_enter},		//circle
	{0x8000, &key_pause},			//square
	{0x1000, &key_weapontoggle},	//triangle

	{0x8, &key_escape},				//start
	{0x1, &key_map},				//select
	
	{0x400, &key_strafeleft},		//L1
	{0x100, &key_speed},			//L2
	{0x800, &key_straferight},		//R1
	{0x200, &key_strafe},			//R2

	{0, NULL},
};


Впилить обработку кнопок оказалось проще чем я думал. Я снизил частоту I2С для улучшения стабильности. Во всяком случае на заявленных 1MHz не пошло. Частоты 100kHz оказалось вполне достаточно для опроса в цикле с задержкой 20ms.

CMake


Убил кучу времени на дописывание CMakeList.txt для компонентов. Что-то не работало с make. И хотелось взять посвежее SDK. Изначальный порт не собирался даже на 3.2.x. Взял esp-idf-v3.3.1 возможно будет работать и на esp-idf-4.0

Звук через ЦАП


На самом деле есть еще один форк. Он отличается подключенной SD-CARD и звуком через встроенный DAC. Первоначальный порт от Espressif позволяет грузить wad файл только во внутреннюю Flash память программ и то надо использовать порезанный файл в котором нет звука!
Схема тут
Идея подключить вместо встроенного DAC внешний меня захватила. Хотя бы и самый копеечный от Cirrus Logic
niwlcwgsprqestpufw2qfwjousq.png
Дальше я настроил DAC на CS4344 и тут меня ждало разочарование. Звук работал с прерываниями. Когда я впиливал в свой проект файл i_sound.c то заметил что один файл dma.h не используется. Как бы ссылка на него есть и сам он есть, но все за комментировано. Может я невнимательно смотрел? Но думаю автор тоже заметил, что со звуком что-то не то и пытался устранить. Возможно устранил и не выложил последний коммит. А может на внутренний ЦАП все работает как надо. Однако выводить звук через встроенный ЦАП и на крошечный динамик можно и пренебречь искажениями-прерываниями. Я поигрался битрейтом и в целом по изменению кода. Это ничего не принесло.

И да, по поводу подключения SD-CARD. Изначально Я повесил ее параллельно дисплею по шине SPI, разведя раздельно сигнал выбор чипа CS. Идея провалилась. Провентилировав вопрос Support SD-SPI bus sharing пришел к выводу что не все SD-CARD сделаны одинаково или мои руки не такие прямые.
пришлось распаять ее через адаптер на плату вместо микрофона. Завелось без подтяжек внешними резисторами к VDD.

Внутренние резисторы справились

    gpio_set_pull_mode(PIN_NUM_MOSI, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(PIN_NUM_MISO, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(PIN_NUM_CLK, GPIO_PULLUP_ONLY);
    gpio_set_pull_mode(PIN_NUM_CS, GPIO_PULLUP_ONLY);

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


На видео версия без звука.
И еще у меня приплавился контакт джойстика для поворота когда паял. В общем первый блин комом

© Habrahabr.ru