cancel
Showing results for 
Search instead for 
Did you mean: 

how to load touchgfx images on fmc_nor flash where external loader is created

jr_engr_mbed
Senior

Hi Team,

After assigning NOR Flash space in the linker, I created an external loader, tested it, and debugged it in CubeProgrammer. @SofLit  suggested to seek help regarding my TouchGFX-related query in a new thread.

Is there any reference or guide available for implementing FMC NOR Flash in a TouchGFX project within CubeIDE? I added my own loader in the debug configuration and debugged it, but no data is shown on the display, nor is anything visible at 0x60000000 in the memory browser.

Please guide me on how to achieve full access via Flash memory.

Regards,

jr_mbed_engr

Screenshot (1339).png

Screenshot (1337).png

Screenshot (1338).png

   my linker file:

 

estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x2000;      /* required amount of heap  */
_Min_Stack_Size = 0x4000; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
  FLASH (rx)     : ORIGIN = 0x08000000, LENGTH = 2048K
  DTCMRAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
  RAM_D1 (xrw)   : ORIGIN = 0x24000000, LENGTH = 512K
  RAM_D2 (xrw)   : ORIGIN = 0x30000000, LENGTH = 288K
  RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K
  ITCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 64K
  EXT_FLASH (r)  : ORIGIN = 0x60000000, LENGTH = 128M
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab (READONLY) : 
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } >FLASH
  .ARM (READONLY) : 
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH

  .preinit_array (READONLY) : 
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH

  .init_array (READONLY) : 
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH

  .fini_array (READONLY) : 
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM_D1 AT> FLASH

  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM_D1

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM_D1

  /* Place IntFlashSection in external flash */
  IntFlashSection :
  {
    . = ALIGN(4);
    *(IntFlashSection)
    . = ALIGN(4);
  } >EXT_FLASH  /* Modified to use external flash */

  ExtFlashSection :
  {
    . = ALIGN(4);
    *(ExtFlashSection*)    /* .ext_flash* sections */
    . = ALIGN(4);
  } >EXT_FLASH
  
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

 

 

15 REPLIES 15

Bring up the NOR Flash as you did with the External Loader  Init(), so clocks, pins, peripheral, ..

You should ideally do this in SystemInit(), but the Cube approach might make that more practical at the beginning of main()

You should be able to confirm / dump the expected content after you've brought the memory up.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
GaetanGodart
ST Employee

Hello @jr_engr_mbed ,

 

You can check our guide on how to setup external flash in memory mapped mode :  flash-external-addressable 
You can also check the guide on external flash in block mode : flash-external-nonaddressable 

 

Don't hesitate to send a new message if you have a specific question.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Hi,

Please confirm if my approach to achieving the external loader functionality is correct so far:

  1. my main doubt is if i use to load already available loader which is given as only one FMC_norflash example in stm32-external loader .github .
  2. if this loader works with my flash, then, it is seem nearly identical and can be used the same loader., as it is 16MB and mine 128MB, but, i 'm enough to use 16MB itself. So, i don't need to worry about creating own loader. Right? or the timing parameter b/w both flash makes any large differences?this is what my assumption so far.,
    so, directly, i need to work with bring up norflash in touchgfx application by initalizing clock,pins, pheripherals.
    like previously, developed project just for norflash testing..
  3. my FMC_nor is followed as non memory mapped? coz, qspi is memory mapped mode.

 

reply for proceeding in one direction.

Thank you for your guidance.

Best regards,

jr_mbed_engr

Screenshot (1359).png

Screenshot (1360).png

  

 

these FMC_norflashes areused in block mode which is Non-Memory-Mapped,

>> a driver must be developed in order for TouchGFX to use the assets stored within.(mentioned in link)

is there any examples for this to do? 

Hi Tesla,

  1. As you suggested, I implemented the test code directly in the main() function of the TouchGFX project. I've already allocated space, and the TouchGFX-generated images are stored in the .ext_flash section. How can I redirect this data to the txbuffer at address 0x60000000? Is the external loader sufficient for displaying the images, or do I need to write a driver for non-memory mapped mode? Is the driver you're referring to the same as the external loader?

So, if I implement my testing code specifically for FMC NOR in the main() function of my TouchGFX application, and use the external loader, will I be able to simply see the output on the display? and example fill data already present here,,>>Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xD20F);

If I need to display image data, should I send the image data to aTxBuffer?

Hello @jr_engr_mbed ,

 

1)
Yes you can use this example, just make sure it works with your project. You might have to change some things but it will be a great starting piont!

2)
Yes, the timings are different for both flash and probably different enough that it won't just work. You will have to use your own timing (c.f. you datasheet)

3)
Yes, your memory (NOR flash using FMC) is probably not memory mapped so it is in block mode.
Have a look at this article to see how to use block mode memory.

 

Regards,

 

 

Gaetan Godart
Software engineer at ST (TouchGFX)

Hello @jr_engr_mbed ,

 

Have you been able to move forward with your issue?

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

No, I didn't manage to make it work. I compressed the image as much as possible to fit it into internal flash, but I still need external memory to store additional data. Today, I realized a few reasons why I was unable to work with NOR flash. I discovered that my external loader was not created properly because I only tested full chip erase and assumed the loader was fine. I followed a guide and finally got the LED to blink, which is how I tested read and write operations before using the loader. Then, I modified only the loader_src.c file from a GitHub project for the NOR flash used in the evaluation board (M29W128GL), changing the size and name to create a loader for my NOR flash (MT28W01ABA). With this loader, I was able to read, write, and perform a full chip erase, but not a sector erase. finally, got error before debug as data is mismatched like 0xff instead 0xe1..(pic attached).. should I create a each and every step as said  here, but this is for qspi.? did anyone followed this for fmc_norflash..? Should I use IAR or CubeIDE? How do I handle FMC-based flash rather than QSPI?

Screenshot (1480).png

 where, i have sdcard slot in custom brd, better go to this option,?.or buying same norflash and use loader directly without creating new one?. we are ready to buy!.

thank you. 

"