Так и не дождавшись DoomWatch платы сделал новый заказ с доставкой Fedex. В этот раз развел платы в KiCad. Как ни странна, Kicad понравился даже больше Eagle AutoDesk
Основная цель была попробовать распаять чип esp32d0wdq6. Не сам готовый модуль, а именно отдельно микросхемой с отдельным Flash и PSRAM. Как это сделано и работает, с видеодемками, читаете и смотрите дальше
Здесь можно прочитать про первую итерация платы
В KiCad как мне показалось все проще. На мой вкус конечно. Немного по другому чем в Eagle Autodesk. Главный плюс в том, что нет ограничения на размер платы если не хотите платить за лицензию. Напомню что в Eagle есть ограничение на размер 100x80мм для бесплатной разработки. Если плата больше надо платить годовую лицензию. По моему, есть также ограничение на количество слоев
Посмотреть 3D View в Eagle я так и не смог. Надо ставить Eagle Fusion 360. В Kicad это отдельный пункт меню. Хотя может я не там смотрел. В общем можно сказать перешел полностью на KiCad
Разделил все на модули, оставив на главной странице то что связано с ESP32 непосредственно. Сам чип и память
Рисовал плату в попыхах. В результате забыл вывести GPIO0. Подвел ее во внешний DAC как MCCLK, а вот вывести на кнопку режима загрузки забыл. Пришлось сдирать лак с дорожки для пайки вывода кнопки. Так же резистор в цепи кварца развел на XTAL_N а в мануале надо на XTAL_P. Повесил резистор несколько Ом, но можно было и перемычку кинуть
Не развелись резисторы Address и Reset для MCP23017. Чипу можно задать адрес I2C тремя выводами. 0x20h когда все три вывода на земле. Все потому что не указал FootPrint
На ошибку не обратил внимания
Перепутал i2C для ES8374. Бывает и такое. В принципе можно использовать переключив 21 -> 22 и 22 -> 21 выводы. Или перерезать дорожки и отскоблить лак, ну как это мы обычно делали с TX RX Uart (Грустный смайл)
На удивление запаяв ESP32 и FLASH плата завелась без каких то проблем. Но, поставив SPRAM, получил бесконечный reboot. Оказался банальный непропай по питанию. Вот бы я искал если ESP32 не припаялся!
Предусмотрел возможность альтернативного опроса кнопок как через мультиплексор MCP23017 так и с помощью ЦАП. На резистивном делителе. Если нет возможности поставить мультиплексор можно задействовать внутренний ADC. По уровню напряжения на входе GPIO34 можно детектировать нажатие кнопки. Минус в том что невозможно опрашивать несколько кнопок одновременно. Плюс соответственно, что не надо дополнительной микросхемы. Только несколько резисторов
Мультиплексор имеет 2 порта по 8 выводов. Один порт, в нашем случае, можно сконфигурировать как выход и повесить на них светодиоды. Хотел предусмотреть мигание если жизни осталось меньше 20% или кончились патроны. Тогда можно будет играть без панели. Получилось реализовать. Остался один зеленый светодиод. Если в комнате нет врагов или в прямой видимости можно подсветить
Для звука, в качестве ЦАП и АЦП применил ES8374. Микросхема содержит встроенный усилитель низкой частоты ~ 1.25 Ватт. Она поддерживается Espressif Audio Development Framework из коробки. В маленьком корпусе QFN-28 получаем Моно ЦАП, АЦП для микрофона и УНЧ с поддержкой SDK. То что надо для такого устройства
Запустил BT Speaker из примера pipeline_bt_sink
Взял в настройках борду lyrat_v4_3. Исправил кодек на AUDIO_CODEC_ES8374_DEFAULT_HANDLE
Настроил порты GPIO
И выкинул инициализацию audio_board_key_init и audio_board_led_init. По правильному надо определять свою кастомную плату
Решил добавить гироскоп L3GD20. Интересная особенность, что его можно подключить как SPI или I2C устройство. R27, R28 в случае подключения по I2C задают адрес
Таким образом на I2C имеем 3 устройства. Управление ADC-DAC ES8374, кнопки на MCP23017 и собственно L3GD20. Запустил все три
Но почемуто L3GD20 не отдает координаты. WHO_AM_I корректо отвечает 0xd4. углы не меняются. У меня нет конденсатора С1 — 10nF, попытался поставить который нашел самый близкий 100nF. Думал пусть хотя бы врет, но похоже не запускается внутрений преобразователь. И это важно
Рассчитал ток подсветки так. Требуется 90mA. Поскольку падение на открытом транзисторе ~0.7V питание для светодиодов подсветки 3.3V — 0.7V = 2.6V. И по закону Ома 2.6V / 0.090A = 28.8 Ohm. Поставил 47 Ohm. Получилось немного темновато. Надо будет уменьшить сопротивление
Также развел Touch XPT2046TS. SPI выводы повесил параллельно дисплею. XPT_CS выведен отдельным выводом. Есть сомнение что заработает. Если бы дисплей не завелся, сделал бы эксперименты. Для приставки он не особо нужен. Взял из примера
Запустил демо LVGL. В настройках примера пробовал выставлять 40MHz для шины SPI. Пример заработал немного быстрее чем на видео
А вот Doom запустился и стабильно работал только на 32MHz. Хотя 26MHz для ILI9341 уже считается разгон
Портов ввода вывода ESP32 не всегда хватает чтобы нафаршировать по максимуму. В этом плане STM32 выглядит привлекательнее. Но у нее нет встроенной поддержки Wi-Fi
В заключении отмечу, что на устройстве можно запустить Nintendo эмулятор ESP32-NESEMU, a Nintendo Entertainment System emulator for the ESP32
Я заказал Game Console с Али. Интересно будет посмотреть что там внутри. Возможно тоже ESP32
Обсуждение и советы жду в комментариях
Основная цель была попробовать распаять чип esp32d0wdq6. Не сам готовый модуль, а именно отдельно микросхемой с отдельным Flash и PSRAM. Как это сделано и работает, с видеодемками, читаете и смотрите дальше
Здесь можно прочитать про первую итерация платы
Boot
Boot Log
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7076
load:0x40078000,len:14600
load:0x40080400,len:4160
0x40080400: _init at ??:?
entry 0x40080684
I (28) boot: ESP-IDF v4.2-dev-2243-gcf056a7d0-dirty 2nd stage bootloader
I (29) boot: compile time 18:51:57
I (30) boot: chip revision: 1
I (33) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (52) boot.esp32: SPI Speed: 40MHz
I (53) boot.esp32: SPI Mode: DIO
I (53) boot.esp32: SPI Flash Size: 8MB
I (56) boot: Enabling RNG early entropy source…
I (62) boot: Partition Table:
I (65) boot: ## Label Usage Type ST Offset Length
I (73) boot: 0 factory factory app 00 00 00010000 000e8000
I (80) boot: 1 wifidata WiFi data 01 02 000fc000 00004000
I (88) boot: 2 wad unknown 42 06 00100000 004f4000
I (95) boot: End of partition table
I (99) boot_comm: chip revision: 1, min. application chip revision: 0
I (106) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x38f98 (233368) map
I (216) esp_image: segment 1: paddr=0x00048fc0 vaddr=0x3ffb0000 size=0x07058 ( 28760) load
I (230) esp_image: segment 2: paddr=0x00050020 vaddr=0x400d0020 size=0x86370 (549744) map
0x400d0020: _stext at ??:?
I (468) esp_image: segment 3: paddr=0x000d6398 vaddr=0x3ffb7058 size=0x04ec4 ( 20164) load
I (478) esp_image: segment 4: paddr=0x000db264 vaddr=0x40080000 size=0x00404 ( 1028) load
0x40080000: _WindowOverflow4 at /esp/v3.3.2/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730
I (479) esp_image: segment 5: paddr=0x000db670 vaddr=0x40080404 size=0x12b7c ( 76668) load
I (538) boot: Loaded app from partition at offset 0x10000
I (538) boot: Disabling RNG early entropy source…
I (549) psram: This chip is ESP32-D0WD
I (551) spiram: Found 64MBit SPI RAM device
I (551) spiram: SPI RAM mode: flash 40m sram 40m
I (555) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (562) cpu_start: Pro cpu up.
I (566) cpu_start: Starting app cpu, entry point is 0x4008191c
0x4008191c: start_cpu0_default at /esp/v3.3.2/esp-idf/components/esp32/cpu_start.c:466
I (0) cpu_start: App cpu up.
I (1454) spiram: SPI SRAM memory test OK
I (1462) cpu_start: Pro cpu start user code
I (1462) cpu_start: Application information:
I (1462) cpu_start: Project name: esp32_doom
I (1466) cpu_start: App version: 085f21b-dirty
I (1472) cpu_start: Compile time: Jul 26 2020 18:51:49
I (1478) cpu_start: ELF file SHA256: 9166eca39a0109f9…
I (1484) cpu_start: ESP-IDF: v4.2-dev-2243-gcf056a7d0-dirty
I (1491) heap_init: Initializing. RAM available for dynamic allocation:
I (1498) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (1504) heap_init: At 3FFCF628 len 000109D8 (66 KiB): DRAM
I (1511) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1517) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1524) heap_init: At 40092F80 len 0000D080 (52 KiB): IRAM
I (1530) spiram: Adding pool of 4096K of external SPI memory to heap allocator
I (1539) spi_flash: detected chip: generic
I (1543) spi_flash: flash io: dio
I (1548) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (1557) spiram: Reserving pool of 32K of internal memory for DMA/internal allocations
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7076
load:0x40078000,len:14600
load:0x40080400,len:4160
0x40080400: _init at ??:?
entry 0x40080684
I (28) boot: ESP-IDF v4.2-dev-2243-gcf056a7d0-dirty 2nd stage bootloader
I (29) boot: compile time 18:51:57
I (30) boot: chip revision: 1
I (33) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (52) boot.esp32: SPI Speed: 40MHz
I (53) boot.esp32: SPI Mode: DIO
I (53) boot.esp32: SPI Flash Size: 8MB
I (56) boot: Enabling RNG early entropy source…
I (62) boot: Partition Table:
I (65) boot: ## Label Usage Type ST Offset Length
I (73) boot: 0 factory factory app 00 00 00010000 000e8000
I (80) boot: 1 wifidata WiFi data 01 02 000fc000 00004000
I (88) boot: 2 wad unknown 42 06 00100000 004f4000
I (95) boot: End of partition table
I (99) boot_comm: chip revision: 1, min. application chip revision: 0
I (106) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x38f98 (233368) map
I (216) esp_image: segment 1: paddr=0x00048fc0 vaddr=0x3ffb0000 size=0x07058 ( 28760) load
I (230) esp_image: segment 2: paddr=0x00050020 vaddr=0x400d0020 size=0x86370 (549744) map
0x400d0020: _stext at ??:?
I (468) esp_image: segment 3: paddr=0x000d6398 vaddr=0x3ffb7058 size=0x04ec4 ( 20164) load
I (478) esp_image: segment 4: paddr=0x000db264 vaddr=0x40080000 size=0x00404 ( 1028) load
0x40080000: _WindowOverflow4 at /esp/v3.3.2/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730
I (479) esp_image: segment 5: paddr=0x000db670 vaddr=0x40080404 size=0x12b7c ( 76668) load
I (538) boot: Loaded app from partition at offset 0x10000
I (538) boot: Disabling RNG early entropy source…
I (549) psram: This chip is ESP32-D0WD
I (551) spiram: Found 64MBit SPI RAM device
I (551) spiram: SPI RAM mode: flash 40m sram 40m
I (555) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (562) cpu_start: Pro cpu up.
I (566) cpu_start: Starting app cpu, entry point is 0x4008191c
0x4008191c: start_cpu0_default at /esp/v3.3.2/esp-idf/components/esp32/cpu_start.c:466
I (0) cpu_start: App cpu up.
I (1454) spiram: SPI SRAM memory test OK
I (1462) cpu_start: Pro cpu start user code
I (1462) cpu_start: Application information:
I (1462) cpu_start: Project name: esp32_doom
I (1466) cpu_start: App version: 085f21b-dirty
I (1472) cpu_start: Compile time: Jul 26 2020 18:51:49
I (1478) cpu_start: ELF file SHA256: 9166eca39a0109f9…
I (1484) cpu_start: ESP-IDF: v4.2-dev-2243-gcf056a7d0-dirty
I (1491) heap_init: Initializing. RAM available for dynamic allocation:
I (1498) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (1504) heap_init: At 3FFCF628 len 000109D8 (66 KiB): DRAM
I (1511) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1517) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1524) heap_init: At 40092F80 len 0000D080 (52 KiB): IRAM
I (1530) spiram: Adding pool of 4096K of external SPI memory to heap allocator
I (1539) spi_flash: detected chip: generic
I (1543) spi_flash: flash io: dio
I (1548) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (1557) spiram: Reserving pool of 32K of internal memory for DMA/internal allocations
KiCad PCB
В KiCad как мне показалось все проще. На мой вкус конечно. Немного по другому чем в Eagle Autodesk. Главный плюс в том, что нет ограничения на размер платы если не хотите платить за лицензию. Напомню что в Eagle есть ограничение на размер 100x80мм для бесплатной разработки. Если плата больше надо платить годовую лицензию. По моему, есть также ограничение на количество слоев
Посмотреть 3D View в Eagle я так и не смог. Надо ставить Eagle Fusion 360. В Kicad это отдельный пункт меню. Хотя может я не там смотрел. В общем можно сказать перешел полностью на KiCad
Разделил все на модули, оставив на главной странице то что связано с ESP32 непосредственно. Сам чип и память
Ошибки
Рисовал плату в попыхах. В результате забыл вывести GPIO0. Подвел ее во внешний DAC как MCCLK, а вот вывести на кнопку режима загрузки забыл. Пришлось сдирать лак с дорожки для пайки вывода кнопки. Так же резистор в цепи кварца развел на XTAL_N а в мануале надо на XTAL_P. Повесил резистор несколько Ом, но можно было и перемычку кинуть
Не развелись резисторы Address и Reset для MCP23017. Чипу можно задать адрес I2C тремя выводами. 0x20h когда все три вывода на земле. Все потому что не указал FootPrint
На ошибку не обратил внимания
Error: Cannot add R10 (no footprint assigned).
Error: Cannot add R9 (no footprint assigned)
Перепутал i2C для ES8374. Бывает и такое. В принципе можно использовать переключив 21 -> 22 и 22 -> 21 выводы. Или перерезать дорожки и отскоблить лак, ну как это мы обычно делали с TX RX Uart (Грустный смайл)
На удивление запаяв ESP32 и FLASH плата завелась без каких то проблем. Но, поставив SPRAM, получил бесконечный reboot. Оказался банальный непропай по питанию. Вот бы я искал если ESP32 не припаялся!
Мультиплексор MCP23017
Предусмотрел возможность альтернативного опроса кнопок как через мультиплексор MCP23017 так и с помощью ЦАП. На резистивном делителе. Если нет возможности поставить мультиплексор можно задействовать внутренний ADC. По уровню напряжения на входе GPIO34 можно детектировать нажатие кнопки. Минус в том что невозможно опрашивать несколько кнопок одновременно. Плюс соответственно, что не надо дополнительной микросхемы. Только несколько резисторов
Мультиплексор имеет 2 порта по 8 выводов. Один порт, в нашем случае, можно сконфигурировать как выход и повесить на них светодиоды. Хотел предусмотреть мигание если жизни осталось меньше 20% или кончились патроны. Тогда можно будет играть без панели. Получилось реализовать. Остался один зеленый светодиод. Если в комнате нет врагов или в прямой видимости можно подсветить
Thread of the health and ammo indicator
void ledTask(void *arg){
while(1){
p = &players[cur_player];
if (p->mo != NULL && p->mo->health < 20) {
mcp23x17_set_level(&dev, 9, on);
} else {
mcp23x17_set_level(&dev, 9, true);
}
if(p->ammo[weaponinfo[p->readyweapon].ammo] < 5){
mcp23x17_set_level(&dev, 10, on);
} else {
mcp23x17_set_level(&dev, 10, true);
}
printf("p->ammo[am_clip] = %d\n", p->ammo[weaponinfo[p->readyweapon].ammo]);
if (p->mo != NULL) {
printf("p->mo->health = %d \n", p->mo->health);
}
printf("Ammo N = %d\n", weaponinfo[p->readyweapon].ammo);
on = !on;
vTaskDelay(1000/portTICK_PERIOD_MS);
}
}
Аудио чип ES8374
Для звука, в качестве ЦАП и АЦП применил ES8374. Микросхема содержит встроенный усилитель низкой частоты ~ 1.25 Ватт. Она поддерживается Espressif Audio Development Framework из коробки. В маленьком корпусе QFN-28 получаем Моно ЦАП, АЦП для микрофона и УНЧ с поддержкой SDK. То что надо для такого устройства
Запустил BT Speaker из примера pipeline_bt_sink
Взял в настройках борду lyrat_v4_3. Исправил кодек на AUDIO_CODEC_ES8374_DEFAULT_HANDLE
Настроил порты GPIO
esp_err_t get_i2s_pins(i2s_port_t port, i2s_pin_config_t *i2s_config)
{
AUDIO_NULL_CHECK(TAG, i2s_config, return ESP_FAIL);
if (port == I2S_NUM_0 || port == I2S_NUM_1) {
i2s_config->bck_io_num = GPIO_NUM_18;
i2s_config->ws_io_num = GPIO_NUM_26;
i2s_config->data_out_num = GPIO_NUM_27;
i2s_config->data_in_num = GPIO_NUM_35;
} else {
memset(i2s_config, -1, sizeof(i2s_pin_config_t));
ESP_LOGE(TAG, "i2s port %d is not supported", port);
return ESP_FAIL;
}
return ESP_OK;
}
И выкинул инициализацию audio_board_key_init и audio_board_led_init. По правильному надо определять свою кастомную плату
Гироскоп L3GD20
Решил добавить гироскоп L3GD20. Интересная особенность, что его можно подключить как SPI или I2C устройство. R27, R28 в случае подключения по I2C задают адрес
// L3GD20H addressesНа GitHub есть библиотека l3gd20h-esp-idf
#define L3GD20H_I2C_ADDRESS_1 0x6a // SDO pin is low
#define L3GD20H_I2C_ADDRESS_2 0x6b // SDO pin is high
Таким образом на I2C имеем 3 устройства. Управление ADC-DAC ES8374, кнопки на MCP23017 и собственно L3GD20. Запустил все три
i2cdetect
i2c-tools> i2cdetect
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — -- — -- — -- — -- — -- — -- — -- — --
10: 10 — -- — -- — -- — -- — -- — -- — -- —
20: — -- — -- 24 — -- — -- — -- — -- — -- —
30: — -- — -- — -- — -- — -- — -- — -- — --
40: — -- — -- — -- — -- — -- — -- — -- — --
50: — -- — -- — -- — -- — -- — -- — -- — --
60: — -- — -- — -- — -- — -- 6a — -- — -- —
70: — -- — -- — -- — -- — -- — -- — -- — --
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — -- — -- — -- — -- — -- — -- — -- — --
10: 10 — -- — -- — -- — -- — -- — -- — -- —
20: — -- — -- 24 — -- — -- — -- — -- — -- —
30: — -- — -- — -- — -- — -- — -- — -- — --
40: — -- — -- — -- — -- — -- — -- — -- — --
50: — -- — -- — -- — -- — -- — -- — -- — --
60: — -- — -- — -- — -- — -- 6a — -- — -- —
70: — -- — -- — -- — -- — -- — -- — -- — --
Но почемуто L3GD20 не отдает координаты. WHO_AM_I корректо отвечает 0xd4. углы не меняются. У меня нет конденсатора С1 — 10nF, попытался поставить который нашел самый близкий 100nF. Думал пусть хотя бы врет, но похоже не запускается внутрений преобразователь. И это важно
i2cdump
i2c-tools> i2cdump -c 0x6a
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: b6 5e 81 fc 05 50 31 83 c4 f9 85 d0 48 c6 00 d4 ?^???P1?????H?.?
10: 1a 15 16 ea c0 b9 4f 72 07 d8 a1 21 a1 00 14 02 ??????Or???!?.??
20: 07 00 00 80 00 00 0c 00 1a 00 13 00 16 00 00 20 ?..?..?.?.?.?..
30: 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 .........?..
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: b6 5e 81 fc 05 50 31 83 c4 f9 85 d0 48 c6 00 d4 ?^???P1?????H?.?
10: 1a 15 16 ea c0 b9 4f 72 07 d8 a1 21 a1 00 14 02 ??????Or???!?.??
20: 07 00 00 80 00 00 0c 00 1a 00 13 00 16 00 00 20 ?..?..?.?.?.?..
30: 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 .........?..
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00…
Дисплей 18 pin ILI9341
Рассчитал ток подсветки так. Требуется 90mA. Поскольку падение на открытом транзисторе ~0.7V питание для светодиодов подсветки 3.3V — 0.7V = 2.6V. И по закону Ома 2.6V / 0.090A = 28.8 Ohm. Поставил 47 Ohm. Получилось немного темновато. Надо будет уменьшить сопротивление
Также развел Touch XPT2046TS. SPI выводы повесил параллельно дисплею. XPT_CS выведен отдельным выводом. Есть сомнение что заработает. Если бы дисплей не завелся, сделал бы эксперименты. Для приставки он не особо нужен. Взял из примера
Демки
Запустил демо LVGL. В настройках примера пробовал выставлять 40MHz для шины SPI. Пример заработал немного быстрее чем на видео
А вот Doom запустился и стабильно работал только на 32MHz. Хотя 26MHz для ILI9341 уже считается разгон
spi_device_interface_config_t devcfg={
.clock_speed_hz=26000000, //Clock out at 26 MHz. Yes, that's heavily overclocked.
.mode=0, //SPI mode 0
.spics_io_num=PIN_NUM_CS, //CS pin
.queue_size=NO_SIM_TRANS, //We want to be able to queue this many transfers
.pre_cb=ili_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
};
Заключение
Портов ввода вывода ESP32 не всегда хватает чтобы нафаршировать по максимуму. В этом плане STM32 выглядит привлекательнее. Но у нее нет встроенной поддержки Wi-Fi
В заключении отмечу, что на устройстве можно запустить Nintendo эмулятор ESP32-NESEMU, a Nintendo Entertainment System emulator for the ESP32
Я заказал Game Console с Али. Интересно будет посмотреть что там внутри. Возможно тоже ESP32
Обсуждение и советы жду в комментариях