O objetivo principal era tentar dessoldar o chip esp32d0wdq6. Não o módulo acabado em si, mas um microcircuito separado com um Flash e PSRAM separados. Como é feito e funciona, com demonstrações em vídeo, leia e veja mais
Aqui você pode ler sobre a primeira iteração do tabuleiro
Bota
Log de inicialização
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
No KiCad, me pareceu mais fácil. Para o meu gosto, é claro. Um pouco diferente do Eagle Autodesk. A principal vantagem é que não há limite para o valor das taxas se você não quiser pagar por uma licença. Deixe-me lembrar que o Eagle tem um limite de tamanho de 100x80mm para desenvolvimento livre. Se a taxa for maior, você terá que pagar uma licença anual. Na minha opinião, também há um limite para o número de camadas
Não consegui ver a visualização 3D no Eagle. É necessário instalar o Eagle Fusion 360. No Kicad, este é um item de menu separado. Embora eu possa não ter olhado lá. Em geral, podemos dizer que mudou totalmente para KiCad.Dividido
tudo em módulos, deixando na página principal o que está diretamente relacionado ao ESP32. O próprio chip e a memória
Erros
Desenhei o tabuleiro em pausas. Como resultado, esqueci de gerar GPIO0. Eu trouxe para um DAC externo como MCCLK, mas esqueci de trazê-lo para o botão de modo de inicialização. Tive que arrancar o verniz da trilha de solda para a saída do botão. Além disso, o resistor no circuito de quartzo foi definido para XTAL_N e no manual é necessário para XTAL_P. Eu desliguei um resistor de vários ohms, mas poderia ter jogado o jumper. Os
resistores Address e Reset para o MCP23017 não se divorciaram. O chip pode ser configurado para o endereço I2C com três pinos. 0x20h quando todos os três pinos estão no solo. Tudo porque não especifiquei o FootPrint
, não prestei atenção ao erro
Erro: Não é possível adicionar R10 (nenhuma pegada atribuída).
Erro: Não é possível adicionar R9 (nenhuma pegada atribuída)
I2C confuso para ES8374. As vezes acontece. Em princípio, pode ser usado trocando os pinos 21 -> 22 e 22 -> 21. Ou corte os trilhos e raspe o verniz, bem, como costumamos fazer com TX RX Uart (sorriso triste).
Surpreendentemente, depois de soldar ESP32 e FLASH, a placa ligou sem problemas. Mas, depois de colocar o SPRAM, tive uma reinicialização sem fim. Acabou sendo uma falta banal de comida. Eu estaria procurando se o ESP32 não estivesse soldado!
Multiplexer MCP23017
Possibilidade de polling alternativo de botões tanto através do multiplexador MCP23017 quanto através do DAC. Em uma divisória resistiva. Se não for possível colocar um multiplexador, você pode usar o ADC interno. Pelo nível de tensão na entrada GPIO34, você pode detectar um pressionamento de botão. A desvantagem é que é impossível consultar vários botões ao mesmo tempo. Além disso, respectivamente, nenhum microcircuito adicional é necessário. Apenas alguns resistores O
multiplexador possui 2 portas de 8 pinos. Uma porta, em nosso caso, pode ser configurada como saída e LEDs podem ser pendurados nela. Queria prever o piscar se a vida útil for inferior a 20% ou se os cartuchos acabarem. Então você pode jogar sem o painel. Acabou sendo realizado. Permanece um LED verde. Se não houver inimigos na sala ou na linha de visão, você pode iluminar
Tópico do indicador de saúde e munição
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);
}
}
Chip de áudio ES8374
Para som, usei ES8374 como um DAC e ADC. O microcircuito contém um amplificador de baixa frequência embutido de ~ 1,25 Watt. É compatível com o Espressif Audio Development Framework . Em um pequeno pacote QFN-28, temos Mono DAC, ADC para microfone e ULF com suporte SDK. O que é necessário para tal dispositivo
Lançado alto-falante BT do exemplo pipeline_bt_sink
Peguei a placa lyrat_v4_3 nas configurações. Codec corrigido em
portas GPIO configuradas AUDIO_CODEC_ES8374_DEFAULT_HANDLE
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;
}
E descartou a inicialização de audio_board_key_init e audio_board_led_init. Pelo correto, você precisa determinar sua placa personalizada
Giroscópio L3GD20
Decidi adicionar um giroscópio L3GD20. Um recurso interessante é que ele pode ser conectado como um dispositivo SPI ou I2C. R27, R28 em caso de conexão via I2C definir o endereço
// L3GD20H endereçosExiste uma biblioteca no GitHub l3gd20h-esp-idf
#define L3GD20H_I2C_ADDRESS_1 0x6a // O pino SDO está baixo
# define L3GD20H_I2C_ADDRESS_2 0x6b // O pino SDO está alto
Assim, temos 3 dispositivos no I2C. Controle ADC-DAC ES8374, botões no próprio MCP23017 e L3GD20. Lançou todos os três
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: — -- — -- — -- — -- — -- — -- — -- — --
Mas por alguma razão, L3GD20 não fornece coordenadas. WHO_AM_I responde corretamente 0xd4. os ângulos não mudam. Não tenho capacitor C1 - 10nF, tentei colocar, que achou o 100nF mais próximo. Pensei mesmo que ele estivesse mentindo, mas parece que o conversor interno não liga. E isso é importante
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…
Exibir 18 pinos ILI9341
Calculou a corrente de luz de fundo da seguinte maneira. Requer 90mA. Visto que a queda do transistor aberto é de ~ 0,7 V, a fonte de alimentação para os LEDs de retroiluminação é 3,3 V - 0,7 V = 2,6 V. E de acordo com a Lei de Ohm 2.6V / 0,090A = 28,8 Ohm. Entregue 47 Ohm. Ficou um pouco escuro. Será necessário reduzir a resistência.Além
disso, o Touch XPT2046TS foi separado. Pinos SPI pendurados em paralelo com a tela. XPT_CS é exibido em um pino separado. Há uma dúvida de que funcionará. Se a tela não tivesse inicializado, eu teria feito experimentos. Para o console, não é particularmente necessário. Tirado do exemplo
Demos
Lançada demonstração LVGL. Nas configurações de exemplo, tentei definir 40 MHz para o barramento SPI. O exemplo funcionou um pouco mais rápido do que o vídeo
Mas o Doom foi inicializado e funcionou de maneira estável apenas a 32 MHz. Embora 26 MHz para ILI9341 já seja considerado overclocking
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
};
Conclusão
As portas de E / S ESP32 nem sempre são suficientes para encher ao máximo. A este respeito, STM32 parece mais atraente. Mas não tem suporte integrado para Wi-Fi.
Concluindo, observo que o dispositivo pode rodar o emulador do Nintendo ESP32-NESEMU e o emulador do Nintendo Entertainment System para o ESP32.
Encomendei o console de jogos com Ali. Vai ser interessante ver o que tem dentro. Possivelmente ESP32 também
Estou ansioso para discussão e conselhos nos comentários.