Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Even enabling PSRAM on boards that support it makes the signal lose sync #22

Open
wgaylord opened this issue Dec 14, 2020 · 5 comments
Open

Comments

@wgaylord
Copy link

wgaylord commented Dec 14, 2020

I have an ESP32 WROVER and I have found if I even enable PSRAM the system loses sync and the text slowly moves down the screen.

I am not sure as to why as the buffers should still be in main ram unless arduino-esp32 changed the functioning of malloc in respect to PSRAM lately.

@wgaylord
Copy link
Author

I found that its specifically the -mfix-esp32-psram-cache-issue line required in the build_flags in platformIO to be the issue I suspect it is somehow affecting caching across all RAM.

@wgaylord
Copy link
Author

Anyone have any idea? Could it be that I have to prevent the other core from running code except during blanking? (Like the cache is getting messed up or something.)

@wgaylord
Copy link
Author

wgaylord commented Feb 4, 2021

Also would it be better to continue using this or move over to the implementation in https://github.com/bitluni/ESP32Lib ?

@ivorss
Copy link

ivorss commented Jun 11, 2021

I was able get rid of the sync issue when using the PSRAM for the back buffer on a ESP32-WROVER-E. The idea is to use core 0 for all the rendering and core 1 to call sendFrameHalfResolution() in a loop.

Problem:

By default the ESP32 Arduino toolset runs setup() and loop() on core 1 of the ESP32. This forces us to use core 0 for calling sendFrameHalfResolution() in a loop. However any time the PSRAM is accessed core 0 is interrupted, which causes all kinds of sync issues. However core 1 is not interrupted, so to solve the problem we need to simply swap the two cores.

Solution:

I was not able to do this is in the Arduino IDE, so I used Eclipse + Sloeber which is much more powerful and flexible development environment. Here are the steps:

  1. Override extern "C" void app_main() so that setup() and loop() are no longer used and move the code to app_main(). This function always starts on core 0, which is what we want. On newer versions of the toolset you have to also undefine CONFIG_AUTOSTART_ARDUINO.
  2. Change the task that calls sendFrameHalfResolution() in a loop to run on core 1.
  3. In CompositeGraphics.init() allocate the back buffer using ps_malloc(). When swapping the buffers in CompositeGraphics.end() use memcpy() to copy the back buffer to the front buffer. Do not swap the pointers. From now on core 1 should never access the back buffer.
  4. At the end of app_main() create an infinite loop and move the code from loop() there. Also add delay(1) after draw().

Effects of the change:

  1. Increased the amount of free RAM by 66K when CompositeGraphics is 300x207.
  2. The framerate dropped from 166 FPS to 45 FPS.

@wgaylord
Copy link
Author

Interesting, I will have to take a look. I have slightly moved on from using composite tho, (Currently using fabgl embed into micropython for VGA)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants