fdivitto / FabGL

ESP32 Display Controller (VGA, PAL/NTSC Color Composite, SSD1306, ST7789, ILI9341), PS/2 Mouse and Keyboard Controller, Graphics Library, Sound Engine, Game Engine and ANSI/VT Terminal
http://www.fabglib.org
Other
1.38k stars 203 forks source link

problems with both ESP-IDF & platformIO compilation #379

Open mtraven opened 2 months ago

mtraven commented 2 months ago

I've been trying to fix fabgl so it will run on IDF, which I see it is suppose to do. It seems there have been some major changes to IDF since the last version of FabGL. I'm able to take care of most the easy stuff, for example esp_adc_cal has changed to esp_adc.

No matter what I do, I get hung up by ULP, not even really sure what it does, but no matter what I do, I get some form of "fatal error: esp32/ulp.h: No such file or directory"

Can someone please have a look & see what need to be done to get this working with a current version of ESP-IDF? Either as a raw IDF, or preferably, as a PIO project.

esp-idf : 5.2.1 (tried rolling back to 4.3.7, not really any change) platform io framework version: v4.5.1 (most recent for PIO-IDF ?) ULP assembler version: 2.28.51-esp-20191205

oh and everything works fine in the arduino version, probably because its an old, pre compiled version of IDF (3.3 as far as I can tell)

adrenlinerush commented 3 weeks ago

@mtraven I got past the ulp.h issue ~/esp/esp-idf/components/ulp/CMakeLists.txt has the include in an if I'm new to esp-idf and cmake so i commented out the if and endif, proper config gets set in sdkconfig but that file gets created on the first run of idf.py build... after the file is created then you can uncomment the if

did you get past the cstring no such file or directory? or error: invalid conversion from 'fabgl::uiTimerHandle' {aka 'void'} to 'TimerHandle_t' {aka 'tmrTimerControl'} [-fpermissive] ? any other changes you made?

adrenlinerush commented 3 weeks ago

I looked in the commits and it supports 4.1.1 i tried that and other 4.x releases of esp-idf... the compiler doesn't like namespace?

Anyone compiling this with esp-idf successfully?

mtraven commented 2 weeks ago

yah, I finally got ULP to work too...real bonehead move on my part, didn't have it turned on in kconfig.

the most advanced IDF I have it running (fully functional) on is IDF 4.4.7. For me, that required no modifications (as I recall, sorry I'm new to IDF too and my project is a 3 month long blur at the moment)

I do recall having issues with namespace, but I cant recall how I resolved it..I kinda think it was directory structure related...if I remember, I'll let you know.

what editor & compiler are you using? You might want to check and make sure its using the framework you think it is. I use vscode & learning how to do that initially was a bit tricky. Pay attention when its compiling, you should see a bunch of references to a given framework, make sure its the one you want. I mention this because, the types of errors you are seeing, are very much like the ones I was seeing when trying IDF 5.0 +. IDF447 should work out of the box.

I did get a version to compile in 5.2.1, but like you, I had to comment some stuff out that I couldn't figure out...so its not functionally, but does technically compile. One day, I'll figure out how to fix that too...I hate using old frameworks

here is a list of the modification I made in trying to get it to run on 5.2.1:

`main fabgl cmake:

add REQUIRES: esp_adc_cal --> esp_adc esp_wifi esp_timer driver spi_flash

general notes: --ulp needs to be in requires & turned on in Konfig

@fabutils.h: --#include --#include

//esp_task_wdt_init(45, false); //method now taks a structs with more info in it: esp_task_wdt_config_t twConfig={.timeout_ms=45, .trigger_panic=false};

*: (f_mkfs(drv, FM_ANY, 16 1024, buffer, FF_MAX_SS) != FR_OK) **f_mkfs has one less command & different params, cant work out, commenting out for now.

@fabui.cpp: -replace killTimer with this (handle recast) void uiApp::killTimer(uiTimerHandle handle) { auto dest = (uiEvtHandler ) pvTimerGetTimerID((tmrTimerControl)&handle);
m_timers.remove(uiTimerAssoc(dest, (tmrTimerControl)&handle)); xTimerStop((tmrTimerControl)&handle, portMAX_DELAY); xTimerDelete((tmrTimerControl)&handle, portMAX_DELAY); } --@ suspendCarrot(): new lines: -- xTimerStop((tmrTimerControl)&m_caretTimer, 0); --xTimerStart((tmrTimerControl*)&m_caretTimer, 0);

@fabui.h: --include

@scene.h: --include

@inputbox.h --include

@serialPort.cpp: change all occurances of: gpio_matrix_in(m_rxPin, URXD_IN_IDX[m_idx], m_inverted); gpio_matrix_out(m_txPin, UTXD_OUT_IDX[m_idx], m_inverted, false);

to: (dropped m_inverted term, new function has fewer params) gpio_iomux_in(m_rxPin, URXD_IN_IDX[m_idx]); gpio_iomux_out(m_txPin, UTXD_OUT_IDX[m_idx], false);

@ cvbsgenerator.cpp rtc_clk_apll_enable(true);//, p.sdm0, p.sdm1, p.sdm2, p.o_div); // cut 4 extra parms

@swgenerator.cpp:

include <driver/gpio.h>

include "soc/io_mux_reg.h"

change gpiomatrix called to gpio_iomux gpio_iomux_out(gpio, I2S1O_DATA_OUT0_IDX + bit, false);

-rtc_clk_apll_enable(false, 0, 0, 0, 0); --> rtc_clk_apll_enable(false); -rtc_clk_apll_enable(true, p.sdm0, p.sdm1, p.sdm2, p.o_div); -->rtc_clk_apll_enable(true);

@ulp_macro_ex.h -- #include "ulp_main.h"

include "ulp.h" (change from esp/ulp.h)

@vgaBaseController.cpp
gpio_matrix--> gpio_iomux_out(gpio, I2S1O_DATA_OUT0_IDX + bit, false);

getDMABuffer(): [void cast return] return (void*)&m_DMABuffers[index].buf;

@ulp_macro_ex: line 150: ESP_LOGW(TAG, "%lu\n", offset); //changd %d to %lu

@vgatextcontroller.cpp gpio_matrix_out --> gpio_iomux_out(gpio, I2S1O_DATA_OUT0_IDX + bit, false);

@vgaDirectController

line:163: return (uint8_t*)&s_DMALines[scanline]->buf; //cast return into uint8_t

@ps2controller.h:

add includes (not sure which one fix RTC_xxxxxx methods, but one did)

include "rtc.h"

include "driver/lp_io.h"

include "hal/rtc_io_hal.h"

include "soc/rtc_io_periph.h"

include "soc/soc_caps.h"`

mtraven commented 2 weeks ago

ohoohoho, I think I remembered the namespace thing.

When I was testing it, I was just using a blank example project. All the IDF example projects are straight "C" projects.....namespaces dont exist in C....hence the issues.

rename your main project file from .c to .cpp and update your cmake file to relfect the new name. that should fix your namespace problem....i think...

adrenlinerush commented 2 weeks ago

thanks a ton for the response!... changing main.c to main.cpp gets it to compile with IDF 4.4.7... I stepped away from this for a bit and was working porting msbasic to my 6502 but I think I'll come back to this now I'm just using vim and cli tools. Prior to this I was using makeEspArduino from the cli. Basically I just wanted to start using IDF so I can create a interrupt handler in asm. I'm using my esp with FabGL as a video card for my 6502 breadboard computer sending 1 byte through a 6522 VIA to the GPIO and reading it and using the FabGL Terminal. The problem is if I get the clock to about 200khz (ive got simple LM555 circuit at about 185khz and if i push it any faster it becomes unstable) the esp can't handle all the interrupts because they're too slow. Ref this: https://haydendekker.medium.com/esp32-interrupts-can-only-do-200khz-56f8dbb6a61c I should be able to easily use a 1mhz oscillator. 20 years in software/IT but just started learning low level hardware and assembly earlier this year so the Xtensa assembly is daunting. I see it gets assembled but not sure if its linked properly, it reboots when it gets an interrupt I'm guessing because it can't exit so I'm probably misunderstanding the REG locations in memory. To get around not having it work with IDF directly I edited the arduino-esp32 CMakeLists.txt and just used makeEspArduino and I can see the file get assembled but now I'm lost.

austin@horizon:~/src/esp32vga32/esp32$ git diff CMakeLists.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 556d377e..8fef28a6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,6 +69,7 @@ set(CORE_SRCS
   cores/esp32/wiring_shift.c
   cores/esp32/WMath.cpp
   cores/esp32/WString.cpp
+  cores/esp32/highint5.S
   )

 set(LIBRARY_SRCS
@@ -211,7 +212,7 @@ set(priv_includes cores/esp32/libb64)
 set(requires spi_flash mbedtls mdns esp_adc_cal wifi_provisioning nghttp wpa_supplicant)
 set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support openssl bt esp_ipc esp_hid)

-idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
+target_link_libraries(${COMPONENT_LIB} "-u ld_include_xt_highint5")

 if(NOT CONFIG_FREERTOS_HZ EQUAL 1000 AND NOT "$ENV{ARDUINO_SKIP_TICK_CHECK}")
     # See delay() in cores/esp32/esp32-hal-misc.c.
@@ -238,7 +239,7 @@ if(CONFIG_AUTOSTART_ARDUINO)
     # linker will always include them.
     #
     # (As they are C++ symbol, we need to add the C++ mangled names.)
-    target_link_libraries(${COMPONENT_LIB} INTERFACE "-u _Z5setupv -u _Z4loopv")
+    target_link_libraries(${COMPONENT_LIB} INTERFACE "-u _Z5setupv -u _Z4loopvi -u ld_include_xt_highint5")
 endif()

 # This function adds a dependency on the given component if the component is included into the build.
austin@horizon:~/src/esp32vga32/esp32$ git remote -v
origin  https://github.com/espressif/arduino-esp32.git (fetch)
origin  https://github.com/espressif/arduino-esp32.git (push)

Here is my attempt at the Xtensa asm interrupt: https://github.com/adrenlinerush/esp32teletype/blob/master/highint5.S

At any rate Thanks again. I'm going to try to get it working with ESP-IDF framework directly now and hopefully I can resolve this...

mtraven commented 2 weeks ago

that is interesting, my current project is a linear encoder system for my lathe (DRO). The esp32 can see 10's of thousands of interrupts in a second. Missing one, throws the whole thing off, so I spent a lot of time trying to optimize that. I dont know assembly, I'm not even a programmer, so that stuff's a bit beyond me. In fact, when I was trying to use sleep, I stopped short of deep sleep because the interrupt handlers for that have to be written in assembly. So, I cant help you there...but it sounds like you've got a direction to follow now, good luck!

ps: Sounds like you probably dont NEED it, but you might check out vscode...IDF has an extension written for it, keeps everything tiddy...and there's a CLI right there if you wanna use it.

adrenlinerush commented 2 weeks ago

yep... 1kHZ = 1000 clock cycles per second so it starts to get unstable around 200,000 interrupts per second. for iot maybe that's plenty? I'm not familiar with how you would interact with a Lathe or a CNC device, I've not worked with that type of equipment. (My lathe is a very simple motor on a belt to turn the spindle LOL) If losing interrupts is a huge deal have you thought of implementing a handshake? IE the interrupt happens, the esp handles what it needs to and then responds with an acknowlegement(ACK). The sending device waits for the ACK before sending the next set of data. It will require adding an input to the esp32. Again not familiar with how your sending data if that is an option.

Very familiar with vscode. I use it every day at work(in Vim mode). Devcontainers is really nice for a team of developers to keep development\testing environments the same. I prefer Vim... I'm just oldschool I guess. Vim with with syntastic and other plugins and the just gdb for my debugger most of the time at home.

mtraven commented 2 weeks ago

I think the handshake would be too slow. Right now, I do the math ( ++ a couple ints) and dump the data in a queue. Then, in a lower priority task, I do a sequence check on what came..this identifies missed steps & reports them. I've got to the point where, even on the bench, I rarely miss an interrupt...and only under circumstances that are well beyond the practical limits when installed.