el objetivo principal era intentar desoldar el chip esp32d0wdq6. No el módulo listo para usar en sí, sino un microcircuito separado con Flash y PSRAM separados. Cómo se hace y funciona, con demostraciones en video, lea y busque más
Aquí puede leer sobre la primera iteración del tablero.
Bota
Registro de arranque
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
PCB KiCad
En KiCad, me pareció más fácil. Para mi gusto, por supuesto. Ligeramente diferente de Eagle Autodesk. La ventaja principal es que no hay límite en el monto de las tarifas si no desea pagar una licencia. Permítanme recordarles que Eagle tiene un límite de tamaño de 100x80 mm para el desarrollo gratuito. Si la tarifa es mayor, debe pagar una licencia anual. En mi opinión, también hay un límite en el número de capas.
No pude ver la vista 3D en Eagle. Es necesario instalar Eagle Fusion 360. En Kicad, este es un elemento de menú independiente. Aunque puede que no haya mirado allí. En general, podemos decir completamente cambiado a KiCad,
dividido todo en módulos, dejando en la página principal lo que está directamente relacionado con ESP32. Chip y memoria en sí
Errores
Dibujé el tablero en pausas. Como resultado, olvidé generar GPIO0. Lo traje al DAC externo como MCCLK, pero olvidé traerlo al botón de modo de descarga. Tuve que arrancar el barniz de la pista de soldadura para la salida del botón. Además, la resistencia en el circuito de cuarzo se configuró en XTAL_N y en el manual es necesario XTAL_P. Colgué una resistencia de varios ohmios, pero era posible lanzar un
puente.Las resistencias de dirección y reinicio del MCP23017 no se divorciaron. El chip se puede configurar en la dirección I2C con tres pines. 0x20h cuando los tres pines están en el suelo. Todo porque no especifiqué FootPrint
, no presté atención al error
Error: no se puede agregar R10 (no se asignó huella).
Error: no se puede agregar R9 (no se asignó huella)
Confundido i2C para ES8374. A veces ocurre. En principio, se puede utilizar cambiando los pines 21 -> 22 y 22 -> 21. O cortar las pistas y raspar el barniz, bueno, como solíamos hacer con TX RX Uart (Sonrisa triste).
Sorprendentemente, después de soldar ESP32 y FLASH, la placa arrancó sin problemas. Pero, habiendo puesto SPRAM, conseguí un reinicio sin fin. Resultó ser una falta banal de comida. ¡Estaría mirando si el ESP32 no está soldado!
Multiplexor MCP23017
Proporcionó la posibilidad de sondeo alternativo de botones tanto a través del multiplexor MCP23017 como usando el DAC. En un divisor resistivo. Si no es posible poner un multiplexor, puede utilizar el ADC interno. Por el nivel de voltaje en la entrada GPIO34, puede detectar la presión de un botón. La desventaja es que es imposible sondear varios botones al mismo tiempo. Además, respectivamente, no se necesita ningún microcircuito adicional. Solo unas pocas resistencias El
multiplexor tiene 2 puertos de 8 pines. Un puerto, en nuestro caso, se puede configurar como salida y los LED se pueden colgar en ellos. Quería prever el parpadeo si la vida útil es inferior al 20% o los cartuchos se han agotado. Entonces puedes jugar sin el panel. Resultó darse cuenta. Queda un LED verde. Si no hay enemigos en la habitación o en la línea de visión, puede iluminar
Hilo del indicador de salud y munición
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 audio ES8374
Para el sonido, usé ES8374 como DAC y ADC. El microcircuito contiene un amplificador de baja frecuencia incorporado ~ 1,25 Watt. Es compatible desde el primer momento con Espressif Audio Development Framework . En el paquete pequeño QFN-28 tenemos Mono DAC, ADC para micrófono y ULF con soporte SDK. Lo que se necesita para un dispositivo de este tipo
Lanzado BT Speaker del ejemplo pipeline_bt_sink
Tomé la placa lyrat_v4_3 en la configuración. Códec fijo en AUDIO_CODEC_ES8374_DEFAULT_HANDLE
Puertos GPIO configurados
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;
}
Y descartó la inicialización de audio_board_key_init y audio_board_led_init. Por el correcto, debe determinar su tablero personalizado
Giroscopio L3GD20
Decidí agregar un giroscopio L3GD20. Una característica interesante es que se puede conectar como dispositivo SPI o I2C. R27, R28 en caso de conexión a través de I2C configure la dirección
// Direcciones L3GD20HHay una biblioteca en GitHub l3gd20h-esp-idf
#define L3GD20H_I2C_ADDRESS_1 0x6a // El pin SDO está bajo
#define L3GD20H_I2C_ADDRESS_2 0x6b // El pin SDO está alto
Por lo tanto, tenemos 3 dispositivos en I2C. Control ADC-DAC ES8374, botones en MCP23017 y el propio L3GD20. Lanzó los tres
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: — -- — -- — -- — -- — -- — -- — -- — --
Pero por alguna razón L3GD20 no da coordenadas. WHO_AM_I responde correctamente con 0xd4. los ángulos no cambian. No tengo un condensador C1 - 10nF, intenté poner cuál encontré el 100nF más cercano. Pensé incluso si estaba mintiendo, pero parece que el convertidor interno no arranca. Y esto es 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…
Pantalla ILI9341 de 18 pines
Calculó la corriente de luz de fondo de la siguiente manera. Requiere 90 mA. Dado que la caída en el transistor abierto es ~ 0,7 V, la fuente de alimentación para los LED de retroiluminación es 3,3 V - 0,7 V = 2,6 V. Y de acuerdo con la Ley de Ohm 2.6V / 0.090A = 28.8 Ohm. Entregado 47 Ohm. Resultó un poco oscuro. Será necesario reducir la resistencia
Además, se separó el Touch XPT2046TS. Los pines SPI colgaban en paralelo con la pantalla. XPT_CS se muestra en un pin separado. Existe la duda de que funcionará. Si la pantalla no se hubiera iniciado, habría hecho experimentos. Para la consola, no es particularmente necesario. Tomó del ejemplo
Población
Se lanzó la demostración de LVGL. En la configuración de ejemplo, intenté configurar 40MHz para el bus SPI. El ejemplo funcionó un poco más rápido que el video.
Pero Doom se puso en marcha y funcionó de forma estable sólo a 32MHz. Aunque 26MHz para ILI9341 ya se considera 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
};
Conclusión
Los puertos de E / S ESP32 no siempre son suficientes para llenar al máximo. En este sentido, STM32 parece más atractivo. Pero no tiene soporte Wi-Fi incorporado.
En conclusión, observo que el dispositivo puede ejecutar el emulador de Nintendo ESP32-NESEMU y el emulador de Nintendo Entertainment System para el ESP32.
Pedí la consola de juegos con Ali. Será interesante ver lo que hay dentro. Posiblemente ESP32 también
Espero la discusión y los consejos en los comentarios.