cancel
Showing results for 
Search instead for 
Did you mean: 

Fail to load images from the SD card

justinjunghkim
Associate

Hello Community member, 

 

I have a STM32F746G-DISCO, which I used to learn touchGFX application. I'm trying to load images from the mini SDCARD, instead of QUADSPI space. I used touchGFX to create a very simple screen to demonstrate, but I was not able to load images from the sd CARD. Could you review my code below, and advise me what I missed? 

 

I tried the following tutorial to learn how to use images from SD CARD (completed till part 3). 

STM32 Graphics: How to Cache Bitmaps Stored on an SD Card, Part 1

I also reviewed the following documents as well:

Caching Bitmaps

Using Non-Memory Mapped Flash for Storing Images

 

Software ver:

  • STM32cubeIDE: 1.17.0
  • STM32CubeMX: 6.13
  • TouchGFX: 4.24.2

 

The below is the codes and explanation of what I did. 

First, I went through all the steps were necessary to setup touchGFX and and STMcubeMX from the part 1. Highlights

  1. PC13 as input pull up
  2. enable SDMMC1
    1. SD 4bits wide bus
    2. DMA RX and TX
    3. SDMMC1 global interrupt enable 
  3. FATFS
    1. enable SD Card
    2. Detect_SDGIO: GPIO input, PC13
  4. FREERTOS
    1. Advanced setting
      1. USE_NEWLIB_REENTRANT -> enable (otherwise cubeMX complains) 

I left the rest setup as default. 

In the tutorial, he used the 3D moving images, but I used fixed image as shown below. The background is box with orange color. 

justinjunghkim_0-1741050496927.png

Second, I setup TouchGFXHAL.cpp file. 

I looked up the bufferSection and located the SDRAM addresses. 

 

//STM32F746G_DISCO.map:
BufferSection 0xc0000000 0x13ec00

 

Based on that, I selected 0xC0200000 for SDRAM cacheStartAddr. And then I reserved 3MB for the cacheSize. 

 

// TouchGFXHAL.cpp file:

// begining of the custom codes:
#include "fatfs.h"

extern uint8_t retSD; /* Return value for SD */
extern char SDPath[4]; /* SD logical drive path */
extern FATFS SDFatFS; /* File system object for SD logical drive */
extern FIL SDFile; /* File object for SD */

__IO uint32_t FatFSInit = 0;
uint32_t bytesread;
// end of the code. 

void TouchGFXHAL::initialize()
{
	// begining of the custom codes:
    uint16_t* cacheStartAddr = (uint16_t*)0xC0200000;
    uint32_t cacheSize = 0x300000; //3 MB, as example

    TouchGFXGeneratedHAL::initialize();

    touchgfx::Bitmap::removeCache();
    touchgfx::Bitmap::setCache(cacheStartAddr, cacheSize, 0); // if dynamic memory is not used then set last param to 0
	// end of the code. 
}

 

 

Then I edited blockCopy as the instruction video suggested. 

 

bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
{
	  // Mount and open the file only once
	if (FatFSInit == 0){
		f_mount(&SDFatFS, (TCHAR const*)SDPath, 0);
		f_open(&SDFile, "images.bin", FA_READ);
		FatFSInit = 1;
	}
	  if ((uint32_t)src >= (uint32_t)0xA0000000 && (uint32_t)src < (uint32_t)0xA0300000)
	  {
		  uint32_t dataOffset = (uint32_t)src - (uint32_t)0xA0000000;
		  f_lseek(&SDFile, dataOffset);
		  f_read(&SDFile, dest, numBytes, (UINT*)&bytesread);
	    return true;
	  }
	  else
	  {
		  return TouchGFXGeneratedHAL::blockCopy(dest, src, numBytes);
	  }
}

 

 

Then I edited STM32F746NGHX_FLASH.ld file for the memory definition and linker script. 

I added SDCARD with a virtual address, and the length. The rest was the default setup. 

 

//STM32F746NGHX_FLASH.ld

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

_Min_Heap_Size = 0xa00 ;  /* required amount of heap  */
_Min_Stack_Size = 0xa00 ; /* required amount of stack */

/* Memories definition */
MEMORY
{
  RAM     (xrw)  : ORIGIN = 0x20000000,  LENGTH = 320K
  FLASH   (rx)   : ORIGIN = 0x08000000,  LENGTH = 1024K
  QUADSPI (r)    : ORIGIN = 0x90000000,  LENGTH = 16M
  SDRAM   (xrw)  : ORIGIN = 0xC0000000,  LENGTH = 8M
  SDCARD  (r)    : ORIGIN = 0xA0000000,  LENGTH = 3M
}

 

 

Then I changed the ExtFlashSection

 

  ExtFlashSection (NOLOAD) :
  {
    *(ExtFlashSection ExtFlashSection.*)
    *(.gnu.linkonce.r.*)
    . = ALIGN(0x4);
  } >SDCARD

 

I noticed that .elf file didn't include images if I put (NOLOAD), so first I built without (NOLOAD), and copied images to the SDCARD, and program it with (NOLOAD). In the instruction tutorial, he used NOLOAD and grab images from the .elf file. 

I used the below command to create images.bin from .elf file. 

 

arm-none-eabi-objcopy.exe --dump-section ExtFlashSection=images.bin STM32F746G_DISCO.elf

 

 

Finally, I edited the screen1View.cpp file.

 

void Screen1View::setupScreen()
{
	Bitmap::cacheAll();
    Screen1ViewBase::setupScreen();
}

void Screen1View::tearDownScreen()
{
	Bitmap::clearCache();
    Screen1ViewBase::tearDownScreen();
}

 

 

When I built the file, I had no issue, and the below is the console message after download files to the DISCO board. 

 


STMicroelectronics ST-LINK GDB server. Version 7.9.0
Copyright (c) 2024, STMicroelectronics. All rights reserved.

Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 1
        Listen Port Number         : 61234
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled
        InitWhile                  : Enabled

Waiting for debugger connection...
Debugger connected
Waiting for debugger connection...
Debugger connected
Waiting for debugger connection...
      -------------------------------------------------------------------
                       STM32CubeProgrammer v2.18.0                  
      -------------------------------------------------------------------



Log output file:   C:\Users\justi\AppData\Local\Temp\STM32CubeProgrammer_a09780.log
ST-LINK SN  : 066BFF3238504B3043232829
ST-LINK FW  : V2J45M31
Board       : 32F746GDISCOVERY
Voltage     : 3.22V
SWD freq    : 4000 KHz
Connect mode: Under Reset
Reset mode  : Hardware reset
Device ID   : 0x449
Revision ID : Rev Z
Device name : STM32F74x/STM32F75x
Flash size  : 1 MBytes
Device type : MCU
Device CPU  : Cortex-M7
BL Version  : 0x90
Debug in Low Power mode enabled

Opening and parsing file: ST-LINK_GDB_server_a09780.srec


Memory Programming ...
  File          : ST-LINK_GDB_server_a09780.srec
  Size          : 221.42 KB 
  Address       : 0x08000000 


Erasing memory corresponding to segment 0:
Erasing internal memory sectors [0 4]
Erasing memory corresponding to segment 1:
Erasing external memory sector 0
Download in Progress:


File download complete
Time elapsed during download operation: 00:00:03.660
Shutting down...
Exit.

 

 

The youtube instruction was clear, and I tried several times, but unfortunately, I was not able to make it work. The below shows the result after the run. 

justinjunghkim_1-1741052840608.png

*the background color is solid orange, just my camera couldn't capture the background color uniformly. 

 

Code that I have in this post was everything I had to modify. Not that much. I searched on the web, but I couldn't find any post similar to my case, so it must be something really simple... 

Thank you in advance. 

 

 

 

1 REPLY 1
Ozone
Lead III

> ... , but I was not able to load images from the sd CARD.

The further text of your post suggests this is not quite correct - an image appears, and at least the dimensions look correct.
I think your code for interpreting and rendering the image has some issues.
You didn't mention the image format you tried to display here.

As a test, you can output a fraction of the image file contents or the whole image on the console, to check you loaded it correctly. But I suppose this is not the issue.

I suppose you need to debug the rendering code.
Most image formats support optional features like compression, usually several different algorithms.
The header section of the file describes all this image details. Check your code to interpret this correctly.
Most PC image viewer applications can output this information for reference.