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

Main Menu

Recent posts

#1
Discussion - EVE / Re: Products with EVE!
Last post by Matrix Orbital - August 12, 2026, 09:14:46 PM
They did a fantastic job on the GUI, and I have to give them extra praise for the way they did the fade in startup screen.
#2
Discussion - EVE / Re: Reset timing inconsistenci...
Last post by BRT Community - July 22, 2026, 04:59:46 PM
Hi Rudolph,

Thanks for your feedback and observations,

We'll review with our R&D team and standardise the recommendation and will keep you informed of the updates on this,

Best Regards, BRT Community


#3
Discussion - EVE / Re: Reset timing inconsistenci...
Last post by Rudolph - July 18, 2026, 05:07:43 PM
And another thing, this is from the BT81x programming manual:

/* Enable backlight of display panel */
#if defined(FT81X_ENABLE)
wr16(REG_GPIOX_DIR, 0xffff);
wr16(REG_GPIOX, 0xffff);
#else
wr8(REG_GPIO_DIR,0xff);
wr8(REG_GPIO,0xff);
#endif
wr8(REG_PCLK,2); //Configure the PCLK divisor to 2, i.e. PCLK = System CLK/2

This does not enable the backlight and it would not be a good idea to enable the backlight at this point since generally the signals need to go out before the backlight is activated.

This is supposed to set the DISP output to HIGH, and it also does.
But why is this setting all the bits in the registers?
DISP is set to output by reset-default in both REG_GPIO_DIR and REG_GPIOX_DIR, so neither of these need to be written to.
And setting all the bits in REG_GPIO or REG_GPIOX does not only set the GPIOx pins to high, it also changes the drive-strength for a couple of pins.

Sure, this might work.
Or it causes problems by for example setting INT_N from Open Drain to Push-pull.

Also, FT81X_ENABLE is not explained.
As the programming guide is for BT81x this might suggest that REG_GPIO_DIR and REG_GPIO are used.
Which would be fine since these are also available in BT81x.

Just keep it simple?

/* Enable DISP signal of display panel */
wr8(REG_GPIO,0x80);
#4
Discussion - EVE / Reset timing inconsistencies
Last post by Rudolph - July 16, 2026, 12:01:45 PM
Hello,
I believe I posted this before, but your documentation is inconsistent and I believe it is wrong.

DS_FT800 states:
"Wake up from POWERDOWN state requires the host to pull the PD_N pin down and
release, a low to high transition enables the 1.2V regulator. POR generated when 1.2V
is stable and FT800 will switch to STANDBY mode after internal oscillator and PLL are up
(maximum 20ms from PD_N rising edge). The clock enable sequence mentioned in
section 4.2.3 shall be executed to proper enable the system clock."

That is a clear and concise statement that the 20ms delay after raising PD_N is required and why.

In the FT81x datasheet this was changed to:
"When in the POWER DOWN state, if the device enters this state via an SPI command, then only the SPI
ACTIVE command will bring the device back to the ACTIVE state, provided PD_N pin is also high.
However, if PD_N is used instead, then making PD_N high followed by a SPI ACTIVE command will wake
up the device."

and
"From the SLEEP state, the host MPU sends an SPI ACTIVE command to wake the FT81x into the ACTIVE
state. The host needs to wait for at least 20ms before accessing any registers or commands. This is to
guarantee the clock oscillator and PLL are up and stable."

This contradicts the FT800 datasheet.
This is also found now in the BT88x, BT817/8, BT815/6 - and I believe it is wrong.

It also contradicts this statement in the BT8178 datasheet:
"After reset the BT817/8 will be in the SLEEP state. Upon receiving the SPI ACTIVE command (or
CLKEXT followed by SPI ACTIVE command if external clock source is used), the clock oscillator and
PLL will start up. Once the clock is stable, the chip will check and repair its internal RAM, running the
configuration and then entering into normal operations. The boot-up may take up to 300ms to
complete. During boot up process, software should not access BT817/8 register or RAM except reading
REG_ID and REG_CPURESET."

So one paragraph states that the host must not read any register directly after ACTIVE,
the other states reading REG_ID is fine.

The BT817/8 programming guide has this:
host_command(ACTIVE);//send host command "ACTIVE" to wake up
delay(300ms);
while (0x7C != rd8(REG_ID));

This is at least consistent with the description as it has a delay() between ACTIVE and reading REG_ID.

Now checking what Bridgetek is using in their own code I found this:

    // Reset the display
    MCU_Delay_20ms();
    HAL_PowerDown(1);
    MCU_Delay_20ms();
    HAL_PowerDown(0);
    MCU_Delay_20ms();
...
    // Set active
    HAL_HostCmdWrite(0, 0x00);

    // Read REG_ID register (0x302000) until reads 0x7C
    uint8_t val;
    while ((val = HAL_MemRead8(EVE_REG_ID)) != 0x7C)
    {
        MCU_Delay_20ms();
        (void)val;
    }


So what is does is adding a delay after setting PD_N to high and it has no delay whatsoever between ACTIVE and the first reading of REG_ID.

To my experience and in accordance with the FT800 datasheet, this is correct.
The delay after setting PD_N is for the EVE chip to go from POWERDOWN to STANDBY.
And reading REG_ID directly after ACTIVE is not a problem, the EVE chip does not answer though untill the internal startup is done which I just measured for a BT817 to happen 43ms after ACTIVE.


The next thing is, why are you using:
host_command(CLKEXT);
host_command(CLKSEL);
host_command(RST_PULSE);
host_command(ACTIVE);

And not:
host_command(RST_PULSE);
host_command(CLKEXT);
host_command(CLKSEL);

host_command(ACTIVE);

From the BT817/8 datasheet:
RST_PULSE
Send reset pulse to BT817/8 core. The
behaviour is the same as POR except
those settings done through SPI
commands will not be affected

So what this meant to say is "host commands"?
Ok, if that is the case, the order should not matter as long as RST_PULSE comes before ACTIVE.


#5
Discussion - EVE / Re: Setting global origin on B...
Last post by BRT Community - July 08, 2026, 02:05:39 PM
Hello Jerome,

Thank you for your question.

It is common for portrait displays to take larger LCD panels and effectively 'cut' these down to the desired size. As you have noticed this results in some 'hidden' pixels being clocked to the screen where the original LCD pixels would have been. This happens because the display driver on the LCD panel usually expects to be driven with the RGB/timing signals for the size of the original LCD panel to ensure the pixel data is latched correctly onto the remaining pixels.

Typically the datasheet for the LCD will provide the timing details for the original display panel size (in your case 360x960). And these are the settings that the BT817 display registers should be configured to use.

However as the BT817 in such a case is clocking data out for pixels that are not physically present on the LCD panel, this can affect where the (0,0) point is on the screen depending on the orientation of the remaining pixels on LCD panel. In your case it sounds like the have remove pixels on the left hand side of the original LCD panel (in portrait orientation), these would be the first to be clocked out by EVE. so in a sense what you see as the (0,0) point on the screen is actually (120,0) in regards to the RGB signals being clocked to the display.

There is no register setting similar to REG_ROTATE which would adjust for this, however it may be possible to adjust the display timing settings such as HOffset or VOffset to shift the RGB signal clocking to align with the pixels available on your display. Please note however this is not possible with all LCD panels.

The best approach to mitigate this behaviour in this case would be to add an offset in code, by either:

  • Using a global variable with your required offset and add this to all of positioning variables used in your display list
  • Or calling VERTEX_TRANSLATE_X and/or VERTEX_TRANSLATE_Y at the beginning of your display lists to let the BT817 compute the required positional change for placing items on the screen


Best Regards,

BRT Community
#6
Discussion - EVE / Setting global origin on BT81X
Last post by jipihorn - July 08, 2026, 09:21:51 AM
Hello,

I'm using a BT817 to drive a adafruit 5799 display, and it works pretty well.
But, there is a specific characteristic of this display : the resolution is given as 240x960, but in reality it is 360x960 with the first 120 pixels hidden. Only a part of the internal memory is actually displayed.
As this display is natively oriented as portrait (the 960 pixels are on the y axis), I use the REG_ROTATE register to change to landscape, but there is this 120 pixels offset I couldn't solve.
Is there a way to set a global origin or a global translation for everything (like the REG_ROTATE) once for all at startup ?

Jerome.
#7
Discussion - EVE / Re: Display images on SD Card ...
Last post by BRT Community - July 06, 2026, 02:02:17 PM
Yes agreed, the zlib compression would reduce storage on the SD card (or MCU flash) but still needs to be inflated to the original size in RAM_G to display it.

As you mentioned, it is good to encode the properties as they are not encoded. Unlike some specific formats such as png, the zlib can be used for different types of file and so does not have the full properties encoded inside.

Best Regards, BRT Community
#8
BRT News / Bridgetek Webinar | From Conce...
Last post by BRT Marketing - July 06, 2026, 05:50:53 AM


🚀 From Concept to Market: EVE in Action

Bridgetek's EVE technology transforms ideas into reality — bridging the gap between design concept and real‑world deployment.

🔹 Smart Interfaces Across Industries
- Medical Devices — intuitive patient monitoring and diagnostics.
- Instrumentation Panels — precision control with sleek GUIs.
- Automotive Dashboards — responsive, modern driver experiences.
- Consumer Devices — everyday products with smarter touch and display.

✨ With EVE, innovation isn't just imagined — it's deployed.

📅 Join our Live Webinar 
🗓 Date: 19 August 2026 
⏰ Time: 3 PM UK Time
👉 Discover how Bridgetek is redefining user interface technology for the future.
Register Now: https://42bmw.share.hsforms.com/2e19HUEPvS0morOulr25CqA
#9
Discussion - EVE / Re: Display images on SD Card ...
Last post by Rudolph - July 01, 2026, 04:46:06 PM
Yes, using zlib compressed files is not about RAM-G usage.
But it would reduce the transfers from the SD card and the SPI traffic to the EVE chip.

I do have Teensy 4.0 and 4.1, but I never really found a use for them apart from implementing the library code. Total overkill. ;)
#10
Discussion - EVE / Re: Display images on SD Card ...
Last post by Turby - July 01, 2026, 09:12:55 AM
Im running this on a Teensy 4.1 which has a builtin SD card, bang for buck these have massive perfomance and great support, only downside is no hardware debugging.

I have come up with a reasonable compromise which uses EVE_memWrite_sram_buffer, and a small 2KB buffer for streaming.
I simply read all raw data files (from EAB) into RAM_G from the SD card at startup. As the raw data does not include the data structure (width, height, format etc) I encode this into the file name and decode and store in a small asset manager data structure on startup.

I've not explored the inflate options, but I suspect that you would still need to reserve the same size uncompressed / raw image size in RAM_G? So apart from smaller image files, no real gain to be had, but I might (hopefully) be wrong!


struct AssetData
{
    char name[32];
    int width;
    int height;

    // when decoding filename, we expect the format and compression to be in the filename, e.g., "my_image_1024x600_ASTC_8X8.raw"
    char format[16];      // e.g., "ASTC"
    char compression[16]; // e.g., "8X8"
    bool isValid;

    uint32_t eveFormat;  // EVE format for this asset, e.g., EVE_COMPRESSED_RGBA_ASTC_8x8_KHR
    uint32_t eveAddress; // Start address in RAM_G (4-byte aligned)
    uint32_t eveSize;    // Total size of the asset in bytes
}; // AssetData


uint32_t GetEveFormat(const char *formatStr, const char *compressionStr)
{
    if (strcmp(formatStr, "ASTC") == 0)
    {
        if (strcmp(compressionStr, "4x4") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_4x4_KHR;
        if (strcmp(compressionStr, "5x4") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_5x4_KHR;
        if (strcmp(compressionStr, "5x5") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_5x5_KHR;
        if (strcmp(compressionStr, "6x5") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_6x5_KHR;
        if (strcmp(compressionStr, "6x6") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_6x6_KHR;
        if (strcmp(compressionStr, "8x5") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_8x5_KHR;
        if (strcmp(compressionStr, "8x6") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_8x6_KHR;
        if (strcmp(compressionStr, "8x8") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_8x8_KHR;
        if (strcmp(compressionStr, "10x5") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_10x5_KHR;
        if (strcmp(compressionStr, "10x6") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_10x6_KHR;
        if (strcmp(compressionStr, "10x8") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_10x8_KHR;
        if (strcmp(compressionStr, "10x10") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_10x10_KHR;
        if (strcmp(compressionStr, "12x10") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_12x10_KHR;
        if (strcmp(compressionStr, "12x12") == 0)
            return EVE_COMPRESSED_RGBA_ASTC_12x12_KHR;

        return EVE_COMPRESSED_RGBA_ASTC_8x8_KHR;
    }

    if (strcmp(formatStr, "RGB332") == 0)
        return EVE_RGB332;

    if (strcmp(formatStr, "RGB565") == 0)
        return EVE_RGB565;

    if (strcmp(formatStr, "L1") == 0)
        return EVE_L1;

    if (strcmp(formatStr, "L2") == 0)
        return EVE_L2;

    if (strcmp(formatStr, "L4") == 0)
        return EVE_L4;

    if (strcmp(formatStr, "L8") == 0)
        return EVE_L8;

    // Default fallback
    return EVE_RGB565;
} // GetEveFormat



AssetData ParseAssetFilename(const char *inputFilename)
{
    AssetData meta = {"", 0, 0, "", "", false};
    char buffer[128];
    strncpy(buffer, inputFilename, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';

    // 1. Get the Name
    char *namePart = strtok(buffer, "_");
    if (namePart)
        strncpy(meta.name, namePart, 31);

    // 2. Get the Resolution string (e.g., "448x456")
    char *resPart = strtok(NULL, "_");

    // 3. Get the Format (e.g., "ASTC")
    char *formatPart = strtok(NULL, "_");
    if (formatPart)
        strncpy(meta.format, formatPart, 15);

    // 4. Get the Compression (e.g., "8X8.raw" -> "8X8")
    char *compPart = strtok(NULL, ".");
    if (compPart)
        strncpy(meta.compression, compPart, 15);

    meta.eveFormat = GetEveFormat(meta.format, meta.compression);

    // Now, safely parse the resolution string separately
    if (resPart)
    {
        char *wStr = strtok(resPart, "x");
        char *hStr = strtok(NULL, "x");
        if (wStr && hStr)
        {
            meta.width = atoi(wStr);
            meta.height = atoi(hStr);
        }
    }

    meta.isValid = true;
    return meta;
} // ParseAssetFilename


void StreamRawFileToEVE(SdFile &file, uint32_t dest_ramg_address)
{
    uint8_t buffer[2048]; // 2KB buffer for streaming
    int bytesRead;
    while ((bytesRead = file.read(buffer, sizeof(buffer))) > 0)
    {
        EVE_memWrite_sram_buffer(dest_ramg_address, buffer, bytesRead);
        dest_ramg_address += bytesRead;
    }
} // StreamRawFileToEVE