شاهد DOOM على ESP32. الجزء الأول

بعد أن جربت التطوير باستخدام وحدات ESP32 الجاهزة ، أردت أن أفعل شيئًا صغيرًا وأصليًا. قررت أن أصنع ساعة. في البداية فكرت في ESP32-PICO-D4 . نظرًا لأنه يحتوي على فلاش 4 ميجا بايت فقط للبرنامج ، فقد قررت إنشاء نسخة كاملة بامتداد يصل إلى 16 ميجا بايت فلاش و 8 ميجا بايت SRAM. مهما كانت الساعة ، يمكنك تشغيل Doom الأول. بشكل عام ، كان هذا كله حشوة كاملة!



ما لم يتم فعله أو يحتاج إلى تحسين:

  1. مؤشر البطارية
  2. تم تنفيذ دائرة حاجز الشحن على الصمام الثنائي Schottky
  3. لا يقع الهوائي بشكل جيد على طبقة أخرى من ESP32

ليس تعليمي!



حسب العرض




قمت بتطبيق شاشة ملونة على وحدة تحكم ST7789 بدقة 240x240. إنه مضغوط ورخيص للغاية. يظهر المزيد والمزيد من برامج التشغيل والمنافذ على الشبكة. على سبيل المثال ، يوجد منفذ لـ LittlevGL ، ولكن لا يوجد عربة يدوية على هذه الشاشة. أعتقد أنه يمكن شراؤها ولصقها. ربما شخص ما لديه خبرة؟ سهم.

قمت بتطوير مجلس واحد على ST7789 وأنها بدأت من دون أي مشاكل.



LittlevGL esp32


عن طريق ملء البرامج وتصحيحها


لقد استخدمت محول CP2102 USB-TO-UART BRIDGE . أولاً ، إنه مضغوط وثانيًا ، مخطط الاتصال بسيط للغاية ولا يتطلب أي أجزاء إضافية تقريبًا.
الخيار 2: يمكن إضافة مكثف 4.7 μF إذا تم تشغيل أجهزة أخرى من المنظم على الشريحة.
إذا قمت بتوصيل REGIN و VBUS بمصدر طاقة USB 5V ، فستحتاج فقط إلى مكثف التحويل عند الإدخال. على الرغم من أنني أعتقد أنه يمكن أن يعمل بدونها. VDD على شريحة في هذه الحالة هو المخرج! لقد ارتكبت خطأ وقمت بتوصيله بدائرة الطاقة 3.3 فولت ولا أستطيع أن أفهم لماذا لدي 4.65 فولت على مصدر الطاقة؟!

يحتوي الرابط في الوثائق أدناه على خيارات للاتصال بطاقة 3.3V. ولكن أعتقد أنه لا توجد حاجة على الإطلاق لتشغيل CP2102 عندما لا نحتاج إلى تحميل الجهاز أو تصحيحه



شحن البطارية مودولو


يقوم المقاوم في LTC4054 بتعيين تيار الشحن:



التغذية


مدعوم ببطاريات 3.7V مع مثبت HT7833. انتاج التيار 500ma. لديها انخفاض صغير في الجهد 300mV ~. LD1117-3.3 لديه المزيد "قليلا".

ملاحظة حول استنتاجات VDD_SDIO. يبلغ خرج مصدر الطاقة هذا 1.8V أو 3.3V ، اعتمادًا على حالة وحدة التحكم الدقيقة IO12 عند بدء التشغيل . 3.3 فولت GPIO12 هو 0 (افتراضي)
VDD_SDIO works as the power supply for the related IO, and also for an external device.

When VDD_SDIO operates at 1.8 V, it can be generated from ESP32’s internal LDO. The maximum currentthis LDO can offer is 40 mA, and the output voltage range is 1.65 V~2.0 V.

When the VDD_SDIO outputs 1.8 V, the value of GPIO12 should be set to 1 when the chip boots and it is recommended that users add a2 kΩ ground resistor and a 4.7 mF filter capacitor close to VDD_SDIO.

When VDD_SDIO operates at 3.3 V, it is driven directly by VDD3P3_RTC through a 6Ωresistor, therefore,there will be some voltage drop from VDD3P3_RTC.

When the VDD_SDIO outputs 3.3 V, the value of GPIO12 is 0 (default) when the chip boots and it is recommended that users add a 1mF capacitor close to VDD_SDIO

هذا مريح للغاية إذا كان لديك فلاش 1.8V. ولكن في حالتي ، سجلت هذا الاستنتاج وربطت فلاش 3V3 و PSRAM بمصدر الطاقة العام.

تستخدم بعض وحدات ESP32 VDD_SDIO ، وبالتالي لا يمكنني تعليق أي شيء من الأجهزة الطرفية على IO12 عند بدء التشغيل. يمكنك ، على سبيل المثال ، تعليق زر. في أحد حلولي ، قمت بتعليق ساق SPI على IO12 ولم تبدأ الوحدة. يبدو أن IO12 حصلت على وحدة من منفذ SPI هذا ، لكنني كنت بحاجة إلى 0 أو العكس. يجب أن يؤخذ هذا في الاعتبار!

جميعا:

صورة

8 ميجابايت PSRAM


8 ميجابايت PSRAM ترقية Mod Mod
دعم لذاكرة الوصول العشوائي الخارجية
PSRAM / CE (pin 1)> ESP32 GPIO 16
PSRAM SO (pin 2)> flash DO
PSRAM SIO [2] (pin 3)> flash WP
PS PSRAM SI (pin 5)> flash DI
PSRAM SCLK (pin 6)> ESP32 GPIO 17
PSRAM SIO [3] (pin 7)> flash HOLD
PSRAM Vcc (pin 8)> ESP32 VCC_SDIO


هوائي ثنائي الفينيل متعدد الكلور


استخدمت هوائي PCB صغير الحجم 2.4 جيجا هرتز . يوجد في مكتبة Eagle Autodesk ويحتل مساحة صغيرة. ربما يمكنك استخدام CERAMIC DIELECTRIC ANTENNA ، ولكن عليك شرائه ، وسعر هوائي PCB أكبر قليلاً. ومع ذلك ، فإن هوائي السيراميك أقل فعالية. أي خيار

دليل اختيار الهوائي السريع تصميم الهوائي وإرشادات تخطيط التردد اللاسلكي مناسب للتحقق من المفهوم.

صورة



قليلا عن مطابقة الهوائي




و إرشادات التصميم ESP32 الأجهزة في الصفحة 7 توفير مبادئ توجيهية لتنفيذ عامل تصفية RF:
معاوقة الخرج لمسامير RF لـ ESP32 (QFN 6 * 6) و ESP32 (QFN 5 * 5) هي (30 + j10) Ω و (35 + j10) respectively ، على التوالي
للحساب ، استخدم أداة الرسم البياني عبر الإنترنت سميث . الفكرة الرئيسية هي الوصول إلى مركز الدائرة عند (30 + j10). ومع ذلك ، فإن هذه البيانات محسوبة ويمكن أن يتأثر الاستخدام الفعلي للمعلمات بسماكة المسارات وثنائي الفينيل متعدد الكلور ، فضلاً عن الموقع المتعلق بالمكونات الأخرى للدائرة.



وهذه ليست الدائرة الوحيدة المطابقة للهوائي. على سبيل المثال ، تكون المطابقة على لوحة esp32-pic مختلفة قليلاً: مخطط سميث

esp32-pico-kit-v4_schematic

ومطابقة المعاوقة

موقع الهوائي والمنطقة الحرة حوله مهمان أيضًا. كما كتبت سابقًا ، في حالتي ، لم يتم اختيار المنصب على النحو الأمثل. ولكن بالنسبة للتكرار الأول للوحة والتحقق من المفهوم ،



سيتم تخصيص الجزء الثاني للوحة نفسها والمنفذ الثالث للبرمجيات. ربما كل شيء يناسبها.

سوف أتقدم قليلاً على منفذ Doom من Espressif Systems. يستخدم المنفذ ILI9341 ، لدينا ST7789. ولكن نظرًا لأن تهيئة المخزن المؤقت ومخرجاته يتم إخراجها في ملف منفصل وتقسيمها إلى طرق منفصلة ، فإن التكيف مع العرض لا يجب أن يسبب صعوبات كبيرة.

  • Ili_init و displayTask مسؤولون عن تهيئة العرض
  • تعتبر DisplayTask مسؤولة عن العرض.

مهمة العرض
void IRAM_ATTR displayTask(void *arg) {
	int x, i;
	int idx=0;
	int inProgress=0;
	static uint16_t *dmamem[NO_SIM_TRANS];
	spi_transaction_t trans[NO_SIM_TRANS];
	spi_transaction_t *rtrans;

    esp_err_t ret;
    spi_bus_config_t buscfg={
        .miso_io_num=-1,
        .mosi_io_num=PIN_NUM_MOSI,
        .sclk_io_num=PIN_NUM_CLK,
        .quadwp_io_num=-1,
        .quadhd_io_num=-1,
        .max_transfer_sz=(MEM_PER_TRANS*2)+16
    };
    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
    };

	printf("*** Display task starting.\n");

    //Initialize the SPI bus
    ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
    assert(ret==ESP_OK);
    //Attach the LCD to the SPI bus
    ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
    assert(ret==ESP_OK);
    //Initialize the LCD
    ili_init(spi);

	//We're going to do a fair few transfers in parallel. Set them all up.
	for (x=0; x<NO_SIM_TRANS; x++) {
		dmamem[x]=pvPortMallocCaps(MEM_PER_TRANS*2, MALLOC_CAP_DMA);
		assert(dmamem[x]);
		memset(&trans[x], 0, sizeof(spi_transaction_t));
		trans[x].length=MEM_PER_TRANS*2;
		trans[x].user=(void*)1;
		trans[x].tx_buffer=&dmamem[x];
	}
	xSemaphoreGive(dispDoneSem);

	while(1) {
		xSemaphoreTake(dispSem, portMAX_DELAY);
//		printf("Display task: frame.\n");
#ifndef DOUBLE_BUFFER
		uint8_t *myData=(uint8_t*)currFbPtr;
#endif

		send_header_start(spi, 0, 0, 320, 240);
		send_header_cleanup(spi);
		for (x=0; x<320*240; x+=MEM_PER_TRANS) {
#ifdef DOUBLE_BUFFER
			for (i=0; i<MEM_PER_TRANS; i+=4) {
				uint32_t d=currFbPtr[(x+i)/4];
				dmamem[idx][i+0]=lcdpal[(d>>0)&0xff];
				dmamem[idx][i+1]=lcdpal[(d>>8)&0xff];
				dmamem[idx][i+2]=lcdpal[(d>>16)&0xff];
				dmamem[idx][i+3]=lcdpal[(d>>24)&0xff];
			}
#else
			for (i=0; i<MEM_PER_TRANS; i++) {
				dmamem[idx][i]=lcdpal[myData[i]];
			}
			myData+=MEM_PER_TRANS;
#endif
			trans[idx].length=MEM_PER_TRANS*16;
			trans[idx].user=(void*)1;
			trans[idx].tx_buffer=dmamem[idx];
			ret=spi_device_queue_trans(spi, &trans[idx], portMAX_DELAY);
			assert(ret==ESP_OK);

			idx++;
			if (idx>=NO_SIM_TRANS) idx=0;

			if (inProgress==NO_SIM_TRANS-1) {
				ret=spi_device_get_trans_result(spi, &rtrans, portMAX_DELAY);
				assert(ret==ESP_OK);
			} else {
				inProgress++;
			}
		}
#ifndef DOUBLE_BUFFER
		xSemaphoreGive(dispDoneSem);
#endif
		while(inProgress) {
			ret=spi_device_get_trans_result(spi, &rtrans, portMAX_DELAY);
			assert(ret==ESP_OK);
			inProgress--;
		}
	}
}


عرض تجريبي سريع للفيديو Esp32-Doom



تم إرسال طلب السبورة إلى مصنع جلكسب.

تم إطلاق التحدي!

All Articles