Closed wangnick closed 10 months ago
Notes on your example for no Jitter: It is not using DMA memory for the buffer. So internally to the core API it is using its own set of DMA buffers that it fills from your memory buffer. Thus, it is a blocking call until it is sent and also causes interrupts to trigger to keep the DMA buffer full as it gets drained. Not an ideal solution or comparison.
I have no in-site into their core code to see the details of what they do or not do that would improve this. Most of the code is derived from their initial code before they exposed the driver model, with a sprinkling of what has been learned by the community. It is not well documented as to what each config does. Lots of trial and error to get it to this point.
One thing you could try until I can find time to look into this more... In the file Esp32_I2c.c, you will find this line
clkm_conf.clka_en = 0;
Change the value to being set to 1. This was on my list to further investigate why examples were disabling the clock for ESP32 but not for other variants (ESPS2/C3, etc).
@wangnick Thanks for being detailed and providing the two example sketches. It helps a lot. I think I have an initial plan for deeper investigate thanks to them.
I am currently investigating the new i2s_std.h API of ESP-IDF 5. It allows non-blocking transmissions. I have some initial example code. But it seemingly also comes with its own set of quirks, refer https://esp32.com/viewtopic.php?f=13&t=37349. Also, its unclear when Arduino-Esp32 will migrate, and when the users will follow ...
Btw, clka_en = 1 was one of the first things I tried, before raising this issue. But I recall it did not help.
Ok, after spending some time with tons of debug code and writing some python to enhance logic analyzer decoder so it calculated the deltas for bits; I can see a 64ns variability in pulse width and the pulse period. I tried every setting difference other than the clock calculation values and it did nothing to improve it.
But when I hardcoded their clock values for a test, it then dropped to 1ns or less variability. This makes me believe that they know from the four hardware clock variables that are applied to make the final frequency, that certain variables will cause less accuracy over others when applying them.
So, I need to reevaluate how the final clock is calculated to try to mimic their priority.
FOUR variables to provide a working clock frequency!
@wangnick I believe I have a solid solution. I still need to test the parallel modes before merging into master, but you can use the following branch to test it out.
you can use the following branch to test it out. https://github.com/Makuna/NeoPixelBus/tree/Esp32I2sJitter
@makuna, I confirm that with the fixes on that branch the ESP32 I2S signal is now stable, with no observable jitter (at 1GSa/s). And my LEDs don't flicker anymore. Well done!
v2.7.8
Describe the bug The data stream produced by NeoEsp32I2s1Ws2812xMethod is jittering between 1200ns and 1263ns per bit.
To Reproduce Compile and deploy attached NeoPixelBusEsp32I2s1Jitter.ino. Check data stream on GPIO27 with oscilloscope.
Expected behavior Bits should always be 1250ns long. Attached Esp32I2s1NoJitter demonstrates that this is possible on ESP32.
Development environment (please complete the following information):
Minimal Sketch that reproduced the problem: NeoPixelBusEsp32I2s1Jitter.ino.txt Esp32I2s1NoJitter.ino.txt
Additional context I recognised the issue because my old WS2812B start flickering when the bit timing is fluctuating.