RudolphRiedel / FT800-FT813

Multi-Platform C code Library for EVE graphics controllers from FTDI / Bridgetek (FT810, FT811, FT812, FT813, BT815, BT816, BT817, BT818)
MIT License
133 stars 58 forks source link

ESP32-S2 with Riverdi RiTFT - WDT IDLE / Backlight PWM #117

Open Ed-Tronics opened 8 months ago

Ed-Tronics commented 8 months ago

Hi Rudolph,

Firstly many thanks for these code libraries, they're really helpful to anyone building projects/products using EVE displays.

I'm working on a project which uses an ESP32-S2 with a Riverdi RiTFT70 display. I used your ESP32 example PIO project and swapped the board config to use my custom ESP32-S2 .json file.

The screen loads just fine when I use the RiTFT50 build flag, which is maybe something to consider updating. My issue is that once the display list has been loaded the Idle task WDT is triggered. Using taskYIELD() or other refactors of this in the while(1) loop doesn't seem to help.

Also there's a gap in my understanding because as far as I can tell the TFT_display function is being called every 20ms and each time it is called the "rotate" is initialised to 0. Rotation is happening normally (I forced tag = 10 as I don't have a touch screen), but how is this so if rotate is being set to 0 every time the function is run?

On a separate subject, your standard PWM frequency for the Riverdi EVE3 backlight is 4kHz, I contacted Riverdi (because I was getting a 4kHz squeal from the IC) who told me the ICs they use for EVE3 are CAT4238 or CAT4139. On the datasheets it states 100 - 2kHz. I recommend 200Hz as a default as this is barely audible.

RudolphRiedel commented 8 months ago

Hello,

ESP32-S2

Espressif is doing too many variants. :-) I do not have one of these.

Riverdi RiTFT70

So BT815, I do have a a RVT5UQBNWC01 and looking at EVE_config.h I wonder why EVE_RiTFT50 is tagged as "untested".

My issue is that once the display list has been loaded the Idle task WDT is triggered. Using taskYIELD() or other refactors of this in the while(1) loop doesn't seem to help.

That is something I occasionally fight with as well, most of all because Espressif keeps changing the ESP-IDF. I do have vPortYield(); at the end of the loop in the main.c of my ESP32 example and the last time I checked this did work. Looks like I need to dig out some ESP32 board from the depths of my desk and connect it to the RiTFT50.

TFT_display function is being called every 20ms and each time it is called the "rotate" is initialised to 0

No, it is only initialized once: static int32_t rotate = 0; The "static" changes the variable from temporary allocated from the stack to allocated from memory and the initialization is only done once.

On a separate subject, your standard PWM frequency for the Riverdi EVE3 backlight is 4kHz, I contacted Riverdi (because I was getting a 4kHz squeal from the IC) who told me the ICs they use for EVE3 are CAT4238 or CAT4139. On the datasheets it states 100 - 2kHz. I recommend 200Hz as a default as this is barely audible.

Phew, that one is on Riverdi then. I just searched for this and found it in their source code: https://github.com/riverdi/riverdi-eve/blob/master/app_layer/App_Common.c Line 830

However, I just checked my RVT5UQBNWC01 and it is populated with a 5 pin chip that is marked with "MU86". So looks like I got a CAT4238 on my module and you are correct, when using the SHDN pin for the PWM the frequency range is 100Hz to 2kHz. The minimum value for REG_PWM_HZ is 250Hz though which is also the default value. Fun.

Thank you, I will fix that! Note though that you can already override this in the platformio.ini: -D EVE_BACKLIGHT_FREQ=250

Ed-Tronics commented 8 months ago

That is something I occasionally fight with as well, most of all because Espressif keeps changing the ESP-IDF. I do have vPortYield(); at the end of the loop in the main.c of my ESP32 example and the last time I checked this did work. Looks like I need to dig out some ESP32 board from the depths of my desk and connect it to the RiTFT50.

I wonder what have they done this time -_- I'll keep working on it and let you know when I make progress with this issue.

No, it is only initialized once: static int32_t rotate = 0; The "static" changes the variable from temporary allocated from the stack to allocated from memory and the initialization is only done once.

Ah interesting, thanks for pointing that out. That's a useful tool.

Thank you, I will fix that! Note though that you can already override this in the platformio.ini: -D EVE_BACKLIGHT_FREQ=250

No problem, glad I could help!

RudolphRiedel commented 8 months ago

I tried using an ESP32 with a RVT5UQBNWC01 / EVE_RiTFT50 now. The first one I found was a XIAO-ESP32-C3 and for some odd reason it is not working at all anymore. No idea why, but I tried two other displays and still it is not working, maybe something in the wiring.

Next I grabbed a BPI-Leaf-S3 and working backwards all three panels just worked. I am using the example from the repository, with the vPortYield() at the end of the loop in main.c.

Listing the dependencies: Resolving ESP32-S3 dependencies... Platform espressif32 @ 6.5.0 (required: espressif32) ├── framework-arduinoespressif32 @ 3.20014.231204 (required: platformio/framework-arduinoespressif32 @ ~3.20014.0) ├── framework-espidf @ 3.50102.240122 (required: platformio/framework-espidf @ ~3.50102.0) ├── tool-cmake @ 3.16.4 (required: platformio/tool-cmake @ ~3.16.0) ├── tool-esptoolpy @ 1.40501.0 (required: platformio/tool-esptoolpy @ ~1.40501.0) ├── tool-idf @ 1.0.1 (required: platformio/tool-idf @ ~1.0.1) ├── tool-mconf @ 1.4060000.20190628 (required: platformio/tool-mconf @ ~1.4060000.0) ├── tool-mkfatfs @ 2.0.1 (required: platformio/tool-mkfatfs @ ~2.0.0) ├── tool-mklittlefs @ 1.203.210628 (required: platformio/tool-mklittlefs @ ~1.203.0) ├── tool-mkspiffs @ 2.230.0 (required: platformio/tool-mkspiffs @ ~2.230.0) ├── tool-ninja @ 1.9.0 (required: platformio/tool-ninja @ ^1.7.0) ├── tool-openocd-esp32 @ 2.1100.20220706 (required: platformio/tool-openocd-esp32 @ ~2.1100.0) ├── tool-riscv32-esp-elf-gdb @ 11.2.0+20220823 (required: espressif/tool-riscv32-esp-elf-gdb @ ~11.2.0) ├── tool-xtensa-esp-elf-gdb @ 11.2.0+20230208 (required: espressif/tool-xtensa-esp-elf-gdb @ ~11.2.0) ├── toolchain-esp32ulp @ 1.23500.220830 (required: platformio/toolchain-esp32ulp @ ~1.23500.0) ├── toolchain-riscv32-esp @ 12.2.0+20230208 (required: espressif/toolchain-riscv32-esp @ 12.2.0+20230208) └── toolchain-xtensa-esp32s3 @ 12.2.0+20230208 (required: espressif/toolchain-xtensa-esp32s3 @ 12.2.0+20230208)

Libraries └── EmbeddedVideoEngine @ 5.0.9 (required: https://github.com/RudolphRiedel/FT800-FT813/archive/refs/heads/5.x.zip)

And that is at least the latest release of Platform espressif32. I tried to use the upstream version of espressif32 but it fails for some reason, complaining at the end that some package.json file is missing.

So this is using ESP-IDF version 5 and since it is a bit outdated it really should not give any new issues. At least like this I do not have an issue with the watchdog.

As I tested with the already changed EVE_config.h I set the backlight-frequency back to 4000 in platformio.ini. It works but yes, it sings, going back to 250Hz and it is quit again. Then I switched to the RVT50HQBNWC00-B / EVE_RVT50H that still uses 4000 in EVE_config.h. And it is quiet - so the RVT50HQBNWC00-B is probably using a different backlight driver than the RVT5UQBNWC01.

Ed-Tronics commented 8 months ago

Hi Rudolph,

Thanks for looking into this.

Next I grabbed a BPI-Leaf-S3 and working backwards all three panels just worked. I am using the example from the repository, with the vPortYield() at the end of the loop in main.c.

All of my packages are identical with the exception of the riscv32-esp and xtensa-esp32s2.

I figure this has something to do with using an S2 rather than S3. However I have found a solution, I followed suggestions to use the following to "feed" the idle task. vTaskDelay(1 / portTICK_PERIOD_MS);

This satisfies my need for now, without disabling it altogether, but I'm unsure why the idle task is timing out every 5s when TFT_display() should run every 20ms. I will try moving the function to an RTOS task using "xTaskCreatePinnedToCore" instead, see if that resolves it.

I wonder whether the difference in our results revolves around the fact that the S3 is dual core whereas the S2 is single.

Then I switched to the RVT50HQBNWC00-B / EVE_RVT50H that still uses 4000 in EVE_config.h. And it is quiet - so the RVT50HQBNWC00-B is probably using a different backlight driver than the RVT5UQBNWC01.

Different frequency for their EVE4 range, I did read something about that on their website now I think about it. Good find! Unfortunately I've found Riverdi's tech support awful so far and they've discontinued their "Hermes" USB to SPI dev board which we need for writing to NOR flash via an EVE3. We're looking at moving over to Matrix Orbital, the only negative being delivery from Canada.

RudolphRiedel commented 8 months ago

I just ordered a S2 mini board as it was cheap on Amazon with delivery tomorrow. And then I seached in PlatformIO and at first could not find a board like this. As it turns out though it is a clone of the Wemos Lolin S2 Mini, so the board ID is "lolin_s2_mini". Searching for "ESP32S2" instead of "ESP32-S2" does yield more results...

I then cleaned out older packages manually from .platformio/packages.

Next I added an entry to my platformio.ini:

[env:ESP32-S2]
board = lolin_s2_mini
build_unflags = -Os
build_flags =
        ${env.build_flags}
         -D EVE_CS=18
         -D EVE_PDN=16
         -D EVE_SCK=33
         -D EVE_MISO=37
         -D EVE_MOSI=35
         -O2

It compiles fine on first try, sort of. Reading CMake configuration... Warning! Flash memory size mismatch detected. Expected 4MB, found 2MB! Please select a proper value in your sdkconfig.defaults or via the menuconfig target!

I really have no idea why it is suddenly required to configure the memory settings instead of using the board configuration.

The module I ordered is advertised with "2MB PSRAM" which would require it to be populated with a ESP32-S2FN4R2. No idea how I could use this PSRAM or where I would configure it, I am curious though if the seller is lying or not.

A different toolchain is used to compile: toolchain-xtensa-esp32s2 @ 12.2.0+20230208 (required: espressif/toolchain-xtensa-esp32s2 @ 12.2.0+20230208)

Well, now I have to wait for the board to check how it behaves.

Different frequency for their EVE4 range, I did read something about that on their website now I think about it. Good find!

I checked their library on Github and they are using 4kHz for all EVE modules.

they've discontinued their "Hermes" USB to SPI dev board which we need for writing to NOR flash via an EVE3.

Oh, I guess this makes sense from their perspective as the EVE4 modules have this mostly undocumented extra connector for factory writing the flash.

EAB has the option to use a Raspberry Pi Pico and I have one wired here to an adapter board. It might be a good idea to design a daughter board for the Raspberry Pi Pico, but I do not actually need one.

We're looking at moving over to Matrix Orbital, the only negative being delivery from Canada.

Yeah, this, I like Matrix Orbital as a company, met the owner and one of the developers a few years back at the Embedded World in Nürnberg, I have used a couple of EVE2 and EVE3 modules. But I do not like to buy from them directly in Canada either, they only offer DDP when shipping to USA, not to Europe. I bought all my Matrix Orbital modules so far from either DigiKey or Mouser. But still nothing available from the EVE4 range. Mouser lists EVE2-USB2SPI-KIT-B, but no stock. I would immediately order an EVE4x-40G-IPS and an EVE4x-70G-IPS-1024600A if these were available from Mouser or DigiKey, plus an EVE2-USB2SPI-KIT-B. Well, supply chain and the last couple of years...

There are other options as well, such as Crystalfontz and Panasys. But I could not order from either of these as I am not aware of any distributors. Crystalfonts is in Spokane Valley, Washington. Panasys is in Shenzen. I am not sure about Panasys though, they wanted to launch BT817 modules, but it does not look like they actually did.

Ed-Tronics commented 8 months ago

I then cleaned out older packages manually from .platformio/packages.

I recently discovered this trick too, it was the only way I could find to silence the complaints when upgrading from esp-idf 6.4.0 to 6.5.0.

Warning! Flash memory size mismatch detected. Expected 4MB, found 2MB!

I have this message too, notice it says flash memory - I think it's referring to the flash storage not PSRAM. "CONFIG_ESPTOOLPY_FLASHSIZE_2MB" in sdkconfig

toolchain-xtensa-esp32s2 @ 12.2.0+20230208

Again, interesting. I've tried to force an update and it insists I have the latest. I'll keep trying.

I bought all my Matrix Orbital modules so far from either DigiKey or Mouser.

Good to know, unfortunately we (as a company) might have to take the hit on import taxes for now. We need to rely on their specified lead times and will be taking the speaker / resistive touch screen / 32MB options which aren't so easily available. We've ordered a couple of the newer EVE-USB2SPI-KIT-B which are capable of supplying the high backlight current required by IPS 7" - 10" displays.

In our investigations we noticed that the pinout for Riverdi and Matrix Orbital is identical (as long as your backlight supply is 3.3V), and therefore we might be able to use the EVE-USB2SPI interface to flash the Riverdi NOR flash. In any case, all these devices do is set the EVE to become a 'dumb' SPI buffer so that the incoming SPI can talk to the flash instead. At least, as far as I can tell!

RudolphRiedel commented 8 months ago

when upgrading from esp-idf 6.4.0 to 6.5.0.

That is not the ESP-IDF version, that is the version of platform-espressif32. It uses ESP-IDF to v5.1.2 which is a bit outdated by now.

Platform-Espressif32 might be needing an update. But so are some more packages.

Warning! Flash memory size mismatch detected. Expected 4MB, found 2MB! I have this message too, notice it says flash memory

Yes, sure, this is the flash-memory, I only wonder why I need to configure this at all when we already have a board description for exactly this kind of stuff.

Good to know, unfortunately we (as a company) might have to take the hit on import taxes for now.

I am ordering for the company from Digikey and Mouser as well.

We need to rely on their specified lead times and will be taking the speaker / resistive touch screen / 32MB options which aren't so easily available.

Yes, true, I would never again use resistive touch though and the price difference between 32mbit and 128mbit is not high enough for me to be concerned about as I am ordering units, not pallets. :-) The fun of doing single digit prototyping / tooling.

We've ordered a couple of the newer EVE-USB2SPI-KIT-B which are capable of supplying the high backlight current required by IPS 7" - 10" displays.

I really hope this is not an issue anymore since EAB should not switch on the backlight anymore in order to just flash the external memory on the module. If it still does I would issue a bug report.

In our investigations we noticed that the pinout for Riverdi and Matrix Orbital is identical (as long as your backlight supply is 3.3V),

I definately can confirm this and at least the smaller EVE4 panels from Riverdi are fine with 3.3V for the backlight.

and therefore we might be able to use the EVE-USB2SPI interface to flash the Riverdi NOR flash.

I just connected my EVE-USB2SPI-A to my RVT50HQBNWC00-B, used EAB in MPSEE mode and it worked just fine detecting the flash. I only did not try to actually flash an image as I already have data on the module.

In any case, all these devices do is set the EVE to become a 'dumb' SPI buffer so that the incoming SPI can talk to the flash instead. At least, as far as I can tell!

No, not really, it uses the co-processor API like one would from a micro-controller. There even is source-code available for the RP2040: https://github.com/Bridgetek/pico-brteve/tree/main/tools/uf2/source

And when you are "only" using 32mbit you could put the flash image in an ESP32 with a big flash and turn that into a production programmer.

I am usually too lazy to connect the EVE-USB2SPI-A, the Hermes board or the PiPico as this would require me to disconnect my controller board and re-connect it later on. And the images I am usually flashing are to test things like UTF-8 fonts, with the limit of 1MB I can easily put these in compressed form in the flash of my controller and then use CMD_INFLATE / CMD_FLASHUPDATE. This way I am at least not disrupting things mechanically.

RudolphRiedel commented 8 months ago

The S2 mini board arrived. I soldered a few pins to it, wired it to one of my adapter boards, connected the RVT50HQBNWC00-B as this was the last module I used the S3 with.

And it just works with no changes to my main.c.

As usual with ESP32, I have no idea what the heck all the memory is used for, but then it really has plenty of it. There is no extra WLAN popping up and the board plays dead on the USB.

Edit: this board really is a bit strange, I need to press reset to start the software, plugging it into the USB is not enough.

Ed-Tronics commented 7 months ago

I just connected my EVE-USB2SPI-A to my RVT50HQBNWC00-B, used EAB in MPSEE mode and it worked just fine detecting the flash.

Excellent news, I'll await my tool and keep my fingers crossed that it works without a hitch.

And it just works with no changes to my main.c.

I'm beginning to think the difference is due to our use of ESP-IDF with Arduino as a component (framework = espidf, arduino). I've disabled the WDT for now while I'm playing with the EVE APIs, layouts etc. It turns out we won't be using an S2 for this project anyway, it will end up being a dual core ESP32 or ESP32-S3. Also the full project uses interrupts and timers to drive tasks so I think this problem will resolve itself once we've integrated everything.

this board really is a bit strange, I need to press reset to start the software, plugging it into the USB is not enough.

That is annoying I agree, we've found that with the Wemos D1 Mini development board too.

RudolphRrr commented 7 months ago

Oh, so you are using Arduino, I was avoiding to use it. :-) I did a number of tests with different Arduino builds including tests with ESP32-S3 and I never needed anything for the watchdog in the loop() function. My example uses the exact same loop() across several Arduinos and that is really like I expect this to work.

For Arduino ESP32 there are two modes available in my library. By default it uses the Arduino SPI class with a buffer for the "burst"-mode. This is because the Arduino SPI class got much faster over the last years and does not use ESP-IDF anymore.

When the macro EVE_USE_ESP_IDF is defined the SPI is using the ESP-IDF directly including DMA transfers for the "burst"-mode, at the cost of not being compatible with the Arduino SPI class.

Ed-Tronics commented 7 months ago

I never needed anything for the watchdog in the loop() function.

This is where our use of Arduino features gets a bit unusual. We don't use the setup() and loop(), we intialise and then use the esp-idf RTOS to create a while(1) task. Our current display uses the TFT_eSPI library which requires Arduino libraries, as well as some IC libraries which use the Arduino SPI.

It might be that we move away from Arduino SPI in the future, at the moment our tft_init looks like this and it works great:

pinMode(EVE_CS, OUTPUT); // Initialise display chip select GPIO SPI.begin(EVE_SCK, EVE_MISO, EVE_MOSI, EVE_CS); // Start SPI

RudolphRrr commented 7 months ago

Ah ok, so your task needs to yield eventually, just like I am using vPortYield(); in the main loop in the ESP32 ESP-IDF example.

It might be that we move away from Arduino SPI in the future, at the moment our tft_init looks like this and it works great:

To my experience, the ESP-IDF implementation of SPI is rather slow, especially for smaller transfers needed to use with extra chips like DACs. It just does a heck of a lot of things over and over again with every single call.

RudolphRiedel commented 7 months ago

I just noticed that there was an update, platform-espressif32 is now at version 6.6.0. It still compiles fine, but the ESP-IDF was updated to v5.2.1, among other things.