Skip to main content
MMerc.1
Associate III
February 25, 2020
Question

How can I use an image stored in µSD ?

  • February 25, 2020
  • 3 replies
  • 1775 views

Hi,

I want to use an image stored in µSD card.

I found the following exemple : STM32Cube_FW_F7_V1.15.0\Projects\STM32746G-Discovery\Applications\Display\LTDC_PicturesFromSDCard

But it is a still image.

What I want to do :

Create the design with TouchGFX. But the size of all images is larger than the size of flash (1 Mo). Can I use an SD card to "replace" objects on the design ?

This topic has been closed for replies.

3 replies

Martin KJELDSEN
Principal III
February 25, 2020

Hi @MMerc.1​,

To do that with TouchGFX you have to use something we call Bitmap Caching. Let me start you off by providing this link - Same would apply for an SD card.

https://support.touchgfx.com/docs/development/ui-development/touchgfx-engine-features/caching-bitmaps

You will need some form of cache in SDRAM and then you usually cache the images you need for a particular screen. But, it impacts render times, so you could cache a lot of images during startup if you have the memory, for instance. There are a variety of options depending on performance requirements and available hardware.

/Martin

MMerc.1
MMerc.1Author
Associate III
February 25, 2020

Hi Martin,

Thank you for your advice.

I will come back to you if I have questions.

MMerc.1
MMerc.1Author
Associate III
February 25, 2020

From what I understand, I have to add the following code in the initialization of TouchGFX :

// Place cache start address in somewhere SDRAM
uint16_t* cacheStartAddr = (uint16_t*)SDRAM_CACHE_START;
uint32_t cacheSize = 0x300000; //3 MB, as example
HAL& hal = touchgfx_generic_init<STM32F4HAL>(dma, display, tc, DISPLAY_WIDTH, DISPLAY_HEIGHT, cacheStartAddr, cacheSize);

I have the following code :

void touchgfx_init()
{
 Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
 TypedText::registerTexts(&texts);
 Texts::setLanguage(0);
 
 FontManager::setFontProvider(&fontProvider);
 
 FrontendHeap& heap = FrontendHeap::getInstance();
 (void)heap; // we need to obtain the reference above to initialize the frontend heap.
 
 hal.initialize();
}

Should I add the previous code after hal.initialize() ?

After that, it talk about SDRAM. Should I add this from CubeMX (Middleware -> FATFS -> External SDRAM) ?

How can I change the address of ExtFlashSection ?

How can I place the entire contents of ExtFlashSection in a single binary file ?

Concerning the platform specific driver, when it talks about "subclass", is it an heritage ?

It is very well explained but it lacks exemples like "Getting started"...

Martin KJELDSEN
Principal III
March 3, 2020

You actually don't have to call touchgfx_generic_init() if you're using the TouchGFX Generator. e.g. But there's no support for cache currently in the Generator. We took it out because it was a bit too application specific.

The below is what you're getting from the Generator in TouchGFXConfiguration.cpp. This is a generated file that will get overwritten if you re-generate.

...
static TouchGFXHAL hal(dma, display, tc, 480, 272);
 
void touchgfx_init()
{
 Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
 TypedText::registerTexts(&texts);
 Texts::setLanguage(0);
 
 FontManager::setFontProvider(&fontProvider);
 
 FrontendHeap& heap = FrontendHeap::getInstance();
 (void)heap; // we need to obtain the reference above to initialize the frontend heap.
 
 hal.initialize();
}

So, what you have to do here is to add the code inside the Generated TouchGFX HAL class (one big user code section where you can write stuff). It implements HAL::initialize() and calls its super class version of the same, so put the re-configuration of BitmapDatabase here - something like:

void TouchGFXHAL::initialize()
{
 // Calling parent implementation of initialize().
 //
 // To overwrite the generated implementation, omit call to parent function
 // and implemented needed functionality here.
 // Please note, HAL::initialize() must be called to initialize the framework.
 
 TouchGFXGeneratedHAL::initialize();
 
 Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(),
 BitmapDatabase::getInstanceSize(),
 bitmapCache,
 bitmapCacheSize,
 numberOfDynamicBitmaps);
}
 
 

MMerc.1
MMerc.1Author
Associate III
March 3, 2020

Hi Martin,

Thank you.

The following variables correspond to :

  • bitmapCache : what does it correspond to ?
  • bitmapCacheSize : what does it correspond to ? What is the maximum value of this section ?
  • numberOfDynamicBitmaps : number of images used in the application (if I have 3 widgets "Image", I need to insert "3" in this section) ?
MMerc.1
MMerc.1Author
Associate III
March 2, 2020

UP please

Tesla DeLorean
Guru
March 2, 2020

>>How can I change the address of ExtFlashSection ? How can I place the entire contents of ExtFlashSection in a single binary file ?

Presumably by modifying the linker script or scatter file. I'd probably figure out a way of letting the linker do the bulk of the work, pretend that SDRAM content, or a portion at least, behaves like FLASH, and then extract the section from the .ELF/.AXF file to file(s) I can put on SD Card, and then load them into SDRAM early in main(), or prior.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
MMerc.1
MMerc.1Author
Associate III
March 3, 2020

Hi Clive,

Thank you.

How can I do this ?