2024-09-02 09:24 AM
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
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) }
}
2024-09-02 09:35 AM
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.
2024-09-03 04:35 AM
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,
2024-09-03 06:23 AM
Hi,
Please confirm if my approach to achieving the external loader functionality is correct so far:
reply for proceeding in one direction.
Thank you for your guidance.
Best regards,
jr_mbed_engr
2024-09-03 09:18 AM
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?
2024-09-03 11:44 AM
Hi Tesla,
2024-09-04 04:20 AM
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?
2024-09-09 06:45 AM
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,
2024-09-30 03:20 AM
Hello @jr_engr_mbed ,
Have you been able to move forward with your issue?
Regards,
2024-09-30 05:44 AM
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?
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.
"