BRT Community

Please login or register.

Login with username, password and session length
Advanced search  

News:

Welcome to the Bridgetek Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ Bridgetek Support

Please refer to our website for detailed information on all our products - Bridgetek - Bridging Technology

Author Topic: Flashing BT815 from ESP32  (Read 483 times)

raffaeler

  • Newbie
  • *
  • Posts: 13
    • View Profile
Flashing BT815 from ESP32
« on: February 17, 2023, 02:41:14 PM »

Hello, after a long pain in making the BT815 work with the ESP32, I can now display commands and some bitmaps.
I now need to be able to update the flash from the microcontroller board.
To do that I started from this sample: https://github.com/MatrixOrbital/EVE3-BT81x-Flash/blob/master/process.c

Anyway, the flashing process does not work as expected.

Problem 1.
Apparently the flash procedure works correctly, but when I disconnect the display and connect to the PC, I read the flash content and there are "random" differences even at the very beginning (offset 0x58 for example). Since the transfer size is larger, there is apparently no space for some error in copying the buffer.
It tried to transfer into the RAM_G_WORKING blocks of 64, 256, 512 and 1K but nothing helps.
Does anybody have some clue?

Problem 2.
During phase boot I print the Flash status and sometimes I see it remains in the INIT status instead of BASIC. Any reason for that?

P.S. The SPI library is the official Arduino for ESP32.

Thank you
Logged
Electronic Engineer, Senior Software Architect, Speaker, Trainer

Rudolph

  • Sr. Member
  • ****
  • Posts: 342
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #1 on: February 18, 2023, 01:38:36 PM »

My library does support the ESP32: https://github.com/RudolphRiedel/FT800-FT813
This includes DMA for both Arduino (by going around the Arduino SPI class) and ESP-IDF.

And in my example code I show how to write to the flash with flash_update, look for the define TEST_UTF8 which is set to "0" by default.
The part that actually writes the flash-image containing an UTF-8 font is commented out with "#if 0" since it only needs to be run once.
Logged

raffaeler

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #2 on: February 22, 2023, 03:28:43 PM »

Hi Rudolph, I could see your huge work (congratulations for that!).
Because of other integrations, I choosed not to work with PlatformIO even if I agree that the plain Arduino IDE is way too basic.
I tried to move your library to the plain Arduino and it was too tricky because of PlatformIO (compiler definitions are not supported by the Arduino IDE but only using the CLI).
Also, I am pretty much done. All I have to do is integrating the "low level" APIs with my own abstraction layer that allows to draw items using OOP and completely forget about commands and the underlying BT C APIs.

Everything works but I am trying to understand what does not work with flashing. Most of the issues I had is because of the very poor documentation. But after reading tons of posts here and examples, I am pretty sure that the code is ok (I also compared the flashing procedure to your code).

I was wondering why BT does not provide a clear documentation of these procedures. Even reading the BT IC datasheet I could not find exhaustive explanations.

Have you ever had problems with unreliable writing on the flash?
Thanks!
Logged
Electronic Engineer, Senior Software Architect, Speaker, Trainer

raffaeler

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #3 on: February 22, 2023, 04:37:29 PM »

I was forgetting one important info.
I carefully observed with the oscilloscope the timings of the ESP32 SPI using both ESP32-IDF (with and without DMA) and the Arduino SPI for ESP32.
The results are:
- The native ESP-IDF performance is poor (even using transactions) because there are lengthy gaps between every transmissions.
- The Arduino SPI library is much way faster.
In the ESP32-IDF forums I was told that the Arduino wrapper does NOT use the IDF abstraction APIs but goes directly to the ESP32 registers. They also said that the IDF library is typically much slower because Espressif wants to provide a stable abstraction over future silicons.
Logged
Electronic Engineer, Senior Software Architect, Speaker, Trainer

raffaeler

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #4 on: February 23, 2023, 12:45:05 PM »

Update: I was able to reliably flash the display with the same code but changing cable.

Anyway, I always have to reboot the display (after flashing), otherwise the FLASH always stay in the "INIT" state and never changes.
How can I make the display flash transitioning from INIT to (at least) BASIC?

Is rebooting after flashing a mandatory action?

TIA
Logged
Electronic Engineer, Senior Software Architect, Speaker, Trainer

Rudolph

  • Sr. Member
  • ****
  • Posts: 342
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #5 on: February 23, 2023, 06:13:43 PM »

Because of other integrations, I choosed not to work with PlatformIO even if I agree that the plain Arduino IDE is way too basic.

I am only using PlatformIO because I would not even call "Arduino IDE 1.x" an IDE and the 2.0 still has nothing that VSCode could not do better.

Quote
I tried to move your library to the plain Arduino and it was too tricky because of PlatformIO (compiler definitions are not supported by the Arduino IDE but only using the CLI).

Hmm, I had an intern for the last two weeks and I gave him an Arduino UNO and an EVE3-50G to play with.
I took my current example and after a little convincing it ran in Arduino IDE 1.8.19.
He used my archive with Arduino IDE 2.0.3 on his own notebook and apart from that the "IDE" killed the project a couple of times it worked fine.

Quote
Also, I am pretty much done. All I have to do is integrating the "low level" APIs with my own abstraction layer that allows to draw items using OOP and completely forget about commands and the underlying BT C APIs.

Well, you still could use my library as a reference point.

Quote
Everything works but I am trying to understand what does not work with flashing. Most of the issues I had is because of the very poor documentation. But after reading tons of posts here and examples, I am pretty sure that the code is ok (I also compared the flashing procedure to your code).

I was wondering why BT does not provide a clear documentation of these procedures. Even reading the BT IC datasheet I could not find exhaustive explanations.

Have you ever had problems with unreliable writing on the flash?

No, I can't recall that I ran into severe issues when I implemented the flash commands.
But then I am probably not a good reference here since I am doing this for a number of years now. :-)
One thing that is important when using these functions though and that is that the alignment requirements must be strictly followed.
This is why I added these to the comment on top of my functions:

Code: [Select]
/* This is meant to be called outside display-list building, it includes executing the command and waiting for completion, does not support cmd-burst.*/
/* write "num" bytes from src in RAM_G to to the external flash on a BT81x board at address dest */
/* note: dest must be 4096-byte aligned, src must be 4-byte aligned, num must be a multiple of 4096 */
/* note: EVE will not do anything if the alignment requirements are not met */
/* note: the address ptr is relative to the flash so the first address is 0x00000000 not 0x800000 */
void EVE_cmd_flashupdate(uint32_t dest, uint32_t src, uint32_t num)
{
    eve_begin_cmd(CMD_FLASHUPDATE);
    spi_transmit_32(dest);
    spi_transmit_32(src);
    spi_transmit_32(num);
    EVE_cs_clear();
    EVE_execute_cmd();
}

And yes, it took a few iterations to make the code this "simple". :-)

I am normally using CMD_INFLATE to get the data into RAM_G since especially fonts are usually highly compressable, probabably because they contain empty glyhps and because all glyphs need to be the same pixel size.

And then flashing from the host controller is not really meant for regular use, for a bigger project with several fonts and images I would flash the image file from EAB with a USB/SPI adapter.

I was forgetting one important info.
I carefully observed with the oscilloscope the timings of the ESP32 SPI using both ESP32-IDF (with and without DMA) and the Arduino SPI for ESP32.
The results are:
- The native ESP-IDF performance is poor (even using transactions) because there are lengthy gaps between every transmissions.
- The Arduino SPI library is much way faster.
In the ESP32-IDF forums I was told that the Arduino wrapper does NOT use the IDF abstraction APIs but goes directly to the ESP32 registers. They also said that the IDF library is typically much slower because Espressif wants to provide a stable abstraction over future silicons.

Oh? When did this change?
When I implemented the ESP32 Arduino code back in end of 2020 it was really really slow.
On a first test with the SPI class my ESP32 was running the display update in 1476µs while the Arduino UNO
was running the exact same code in 516µs.
https://github.com/RudolphRiedel/FT800-FT813/issues/14

The SPI class was running on top of ESP-IDF back then.

So I may need to try this again.
What I am not seeing in the current ESP32 SPI class is DMA support though.
And what I do see is that there is a heck of a lot of code that gets executed everytime in order to try to make the implementation bullet proof.
So even if it really is running faster it still is running with the handbrake engaged.

Update: I was able to reliably flash the display with the same code but changing cable.

Anyway, I always have to reboot the display (after flashing), otherwise the FLASH always stay in the "INIT" state and never changes.
How can I make the display flash transitioning from INIT to (at least) BASIC?

Is rebooting after flashing a mandatory action?

No, there is no need to put the flash thru the init state, it even should go thru the init automatically and reach BASIC state.

From my example, shortened a little:

Code: [Select]
void TFT_init(void)
{
    if(E_OK == EVE_init())
    {
         EVE_memWrite8(REG_PWM_DUTY, 0x30);  /* setup backlight, range is from 0 = off to 0x80 = max */
        touch_calibrate();

    #if 0
        /* this is only needed once to transfer the flash-image to the external flash */
        uint32_t datasize;

        EVE_cmd_inflate(0, flash, sizeof(flash)); /* de-compress flash-image to RAM_G */
        datasize = EVE_cmd_getptr(); /* we unpacked to RAM_G address 0x0000, so the first address after the unpacked data also is the size */
        EVE_cmd_flashupdate(0,0,4096); /* write blob first */
        if (E_OK == EVE_init_flash())
        {
            EVE_cmd_flashupdate(0,0,(datasize|4095)+1); /* size must be a multiple of 4096, so set the lower 12 bits and add 1 */
        }
    #endif

        if (E_OK == EVE_init_flash())
       {
          EVE_cmd_flashread(MEM_FONT, 84928, 320); /* copy .xfont from FLASH to RAM_G, offset and length are from the .map file */
       }
...
}

This code assumes that the flash is completely empty and it does not bother to check the state of the flash first since there practically is no way
that a correctly attached flash is not in state BASIC at this point, especially not after full initialization of the display.
The first 4k contain the binary blob that is necessary to put the flash into state FULL so this is flashed first.
After that my EVE_init_flash() function is called to put the flash into state FULL - and it does a whole lot more than just that, have a look.
If the flash was sucessfully initialized to state FULL the whole image is flashed with CMD_FLASHUPDATE.
The next call to EVE_init_flash() is only there as the block that flashes the image can be commented out after the first time.

So even on a first run with flash update active this just runs thru, no need for a reset at all.

And the only reason I am doing this in two steps is that writing to the flash is a lot faster in state FULL.

If the flash is viable then REG_FLASH_STATUS automatically indicates state BASIC after power-up and from there you can use CMD_ FLASHERASE, FLASHWRITE, FLASHUPDATE, FLASHPROGRAM, FLASHREAD and FLASHDETACH.
« Last Edit: February 24, 2023, 03:46:26 PM by Rudolph »
Logged

raffaeler

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #6 on: March 01, 2023, 08:01:28 AM »

Quote
I am only using PlatformIO because I would not even call "Arduino IDE 1.x" an IDE and the 2.0 still has nothing that VSCode could not do better.

Look, I already wrote that Arduino IDE is not good, but I can't migrate the rest of the libraries just because of this. I have good reasons for this choice and I know what I am speaking of.


Quote
Hmm, I had an intern for the last two weeks and I gave him an Arduino UNO and an EVE3-50G to play with.
I took my current example and after a little convincing it ran in Arduino IDE 1.8.19.
He used my archive with Arduino IDE 2.0.3 on his own notebook and apart from that the "IDE" killed the project a couple of times it worked fine.

Oh sure, I can fork the library but then I have to maintain it and keep aligned.... better not.
As I wrote, I am already at a good develpment stage. I already have wrote my own decompiler to rebuild the exact sequence of the commands and a code generator that generates the code using my libraries. I am just trying to fill the gaps due to the very poor documentation.

Quote
Well, you still could use my library as a reference point.

Thanks, I did it, but I discovered that the issue was a poor flat cable.

Quote
Oh? When did this change?
When I implemented the ESP32 Arduino code back in end of 2020 it was really really slow.

I don't know. This is what I could see on the oscilloscope and that was confirmed by the ESP32 discord channel.

Quote
No, there is no need to put the flash thru the init state, it even should go thru the init automatically and reach BASIC state.

I am not setting the INIT state. After successfully flashing I read the state and it transitions to INIT without ever going to basic. If I then reboot, everything is ok and I can transition to FULL as well.


TIA
Logged
Electronic Engineer, Senior Software Architect, Speaker, Trainer

Rudolph

  • Sr. Member
  • ****
  • Posts: 342
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #7 on: March 06, 2023, 05:23:13 PM »

Quote
I am only using PlatformIO because I would not even call "Arduino IDE 1.x" an IDE and the 2.0 still has nothing that VSCode could not do better.

Look, I already wrote that Arduino IDE is not good, but I can't migrate the rest of the libraries just because of this. I have good reasons for this choice and I know what I am speaking of.

Relax? I believe you misread my "I did" with "you have to".

Quote
Quote
No, there is no need to put the flash thru the init state, it even should go thru the init automatically and reach BASIC state.

I am not setting the INIT state. After successfully flashing I read the state and it transitions to INIT without ever going to basic. If I then reboot, everything is ok and I can transition to FULL as well.


TIA

I just added two reads for REG_FLASH_STATUS, one directly after my EVE_init() function which does nothing with the flash
and one later.
And with not using the flash the values are 2 and 2 which means that the flash is in state BASIC.

When I add a CMD_FLASHERASE() in between it stays 2 / 2.
When I throw in a CMD_FLASHUPDATE for the first block I still get 2 / 2.
When I swith to use CMD_FLASHUPDATE for the whole 85k flash image I still get 2 / 2.
This all is without using CMD_FLASHFAST.

I added an EVE_init_flash() and it changed to 2 / 3, so the flash is in state FULL.

Throwing in a CMD_FLASHERASE() I get 2 / 2 the next time after that and 0xE002 from CMD_FLASHFAST - no header detected in sector 0.

Ok, now I got 1 / 1 on coldstart and it does not go away with a reset of the controller.
I can not reproduce it though, the next coldstart it is 2 / 2 again.

So there is something there, I only can not reproduce it reliably.
Maybe some race condition that somehow locks up the QSPI of the flash chip?

I added three more EVE_init_flash() after the first in between in hope I get a 1 / 2 with maybe on the third EVE_init_flash()
that the flash starts working somewhere alone the lines.
But nothing, does not happen anymore, not after 2 seconds cold or 2 minutes, also not when bringing down the current from the bench PSU
to close what the dispay draws.

I triggered it with a little under-voltage which probably did odd things to  my backligh-supply.
And the repeated calls of EVE_init_flash() do nothing.

Now I added a delay of 100ms before calling my EVE_init() function and it works even with the PSU voltage lower than
my backlight voltage.

So at least what I get here looks like a supply issue, bringing EVE out of reset before the voltage rails are stable.
« Last Edit: March 07, 2023, 05:53:51 AM by Rudolph »
Logged

raffaeler

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #8 on: March 08, 2023, 04:54:41 PM »

Quote from: Rudolph
Ok, now I got 1 / 1 on coldstart and it does not go away with a reset of the controller.
I can not reproduce it though, the next coldstart it is 2 / 2 again.

So there is something there, I only can not reproduce it reliably.
Maybe some race condition that somehow locks up the QSPI of the flash chip?

This is exactly the issue I see. Thank you for testing.
I don't believe there is a race condition. Apparently in the oscilloscope I see the correct traffic.

Anyway, it looks like a timing issue. It may depend on the SPI being too fast. When I tested the SPI code I could see the display I had to slow down some requests/responses. Unfortunately there is no better documentation to diagnose the issue. The timing diagrams are pretty basic.


Quote from: Rudolph
I added three more EVE_init_flash() after the first in between in hope I get a 1 / 2 with maybe on the third EVE_init_flash()
that the flash starts working somewhere alone the lines.
But nothing, does not happen anymore, not after 2 seconds cold or 2 minutes, also not when bringing down the current from the bench PSU
to close what the dispay draws.

I triggered it with a little under-voltage which probably did odd things to  my backligh-supply.
And the repeated calls of EVE_init_flash() do nothing.

Now I added a delay of 100ms before calling my EVE_init() function and it works even with the PSU voltage lower than
my backlight voltage.

So at least what I get here looks like a supply issue, bringing EVE out of reset before the voltage rails are stable.

I did check the voltage on the board and it's good and stable over time.
Logged
Electronic Engineer, Senior Software Architect, Speaker, Trainer

Rudolph

  • Sr. Member
  • ****
  • Posts: 342
    • View Profile
Re: Flashing BT815 from ESP32
« Reply #9 on: March 12, 2023, 02:08:42 PM »

Anyway, it looks like a timing issue. It may depend on the SPI being too fast. When I tested the SPI code I could see the display I had to slow down some requests/responses. Unfortunately there is no better documentation to diagnose the issue. The timing diagrams are pretty basic.

I am not saying that it is not a timing issue but the flash is on it's own QSPI bus and compared to the 133MHz the flash chips usually support, it is slow.
Logged