Doom Boy ESP32

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



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

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

    Сделана попытка запуска внешнего АЦП CS4344.

    Doom от Espressif


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



    Автор порта предлагал сделать
    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




    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



    Дальше я настроил 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.

    Надо бы сделать еще одну редакцию печатной платы. Эта никуда не годится!


    На видео версия без звука.

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

    UPD

    Удалось наладить звук. Рывки присутствуют, но уже не критичные. Изменения в коде:

    spi_lcd.c
    dmamem[x]=heap_caps_malloc(MEM_PER_TRANS*2, MALLOC_CAP_DMA);

    i_sound.c
    void IRAM_ATTR updateTask(void *arg)
    {
    // size_t bytesWritten;
    while(1)
    {
    I_UpdateSound();
    i2s_write(I2S_NUM_0, mixbuffer, SAMPLECOUNT*SAMPLESIZE, &bytesWritten, portMAX_DELAY);
    }
    }


    .dma_buf_count = 2,
    .dma_buf_len = 512,


    xTaskCreatePinnedToCore(&updateTask, "updateTask", 1000, NULL, 7, NULL, 0);
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 12

      0
      Огонь!!!
      Положил в закладки для повторения в перспективе.
      Тем более что дум люблю с молодости.
        +5
        Хм, вайфай так и просит организовать возможность поднятия своего сервера с доступом к нему клиентов с такими же девайсами… Дефматч в дум с коллегой на самособраных железках по вайфаю… Короче, прямо вижу джостикоподобные отладки с есп32 с экраном заточеннык под дум)
          0
          И вы правы. Есть такое расширение для Doom. Но его надо портировать в ESP32
          Chocolate Doom has rewritten and enhanced multiplayer code
          Multiplayer
          0
          Вот эти окошки в первой комнате на первом уровне — гениально! Ты ходишь и (на легком уровне) никого нет. Па сложном там уж ЕМНИП гады с шотганами и все такое… Но на легком — пусто. И в окно посмотреть можно, и светло все, яркие цвета… Лепота!!! Но музон нагнетает чувство опасности, визуально — все норм еще, но ты ждешь, что ща начнется! Другие игрушки — сразу что-то взрывается, кого-то надо убить, тьма-кровь-кишки — а первый DOOM он вот такой, чистое светлое помещение и окна в светлый красивый мир… :-)
            +2
            Кто бы мог подумать лет десять назад, что будет возможность собрать игровую приставку на коленке, тем более не сюбор и даже не сегу, а с первым крутым контентом интернет-клубов девяностых. Соберу однозначно!
              0

              Круто! А в детстве на приставке 3DO Doom тормозил безбожно, приходилось уменьшать размер окна.

                0
                Ну вроде как одним из самых неудачных портов считается.
                Зато музыка.
                www.youtube.com/watch?v=lLpHArM3ip0
                  0
                  У меня был 486SX с распаянным на метеринке процом. мой знакомый на 386 ставил худшее качество в игре. Кнопка F5 если не ошибаюсь. даже с разогнанным процом у него было медленее чем у меня. 4Kb кэша первого уровня это сила!
                  486SX также не имел аппаратной float point. Doom ее не использовал что давало такому обрезку явное преимущество
                  0
                  Не совсем понял, он на голом железе работает через HAL прослойку или требует какую-то ОСРВ?
                    0
                    Используется FreeRTOS для запуска потоков и семафоры

                    xTaskCreatePinnedToCore(&doomEngineTask, "doomEngine", 22480, NULL, 5, NULL, 0);


                    +1
                    Вспомнил, как будучи совсем ребенком и насмотревшись в одном из первых русскоязычных журналов про PC игры («Корона» Видео Асс) на DOOM, я недолго думая разобрал свой любимый ч/б Тетрис с намерением что нибудь там покрутить, но получить DOOM на выходе, пусть и в ч/б ))
                    Идея по теперь уже понятным причинам провалилась, да и программистом я так и не стал, но автор закрыл мой гештальт, спасибо!
                      0
                      Есть много портов под разные семейства микроконтроллеров

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое