I'm guessing that the problem is related to the fact that the code you are copying to RAM is compiled and linked for execution out of Flash, not RAM. In addition, there is an easier way to perform the copy operation and then reference the two functions in RAM. I'm attaching a modified project that implements what I'll briefly describe.
First in the SEGMENTS section of your .prm file, you'll want to replace
SHADOW_RAM_S = READ_WRITE 0x001000 TO 0x0011FF; // 512 for functions that will be copied to RAM
with:
SHADOW_ROM_S = READ_ONLY 0xFFFC00 TO 0xFFFDFF RELOCATE_TO 0x001000; // 512 for funtions that will be copied to RAM
and remove "SHADOW_ROM_S" from /* non-paged FLASHs */
This will tell the linker to place the code in Flash from 0xFFFC00 TO 0xFFFDFF but to link it to address 0x001000.
Remove:
SHADOW_RAM INTO SHADOW_RAM_S; /* Reserve Shadow ROM to copy flash related functions here */
from the PLACEMENTS section.
Next, replace your Copy_Shadow() function with:
/*************************************************************************************/
#define __SEG_START_REF(a) __SEG_START_ ## a
#define __SEG_END_REF(a) __SEG_END_ ## a
#define __SEG_SIZE_REF(a) __SEG_SIZE_ ## a
#define __SEG_START_DEF(a) extern char __SEG_START_REF(a) []
#define __SEG_END_DEF(a) extern char __SEG_END_REF( a) []
#define __SEG_SIZE_DEF(a) extern char __SEG_SIZE_REF( a) []
__SEG_START_DEF(SHADOW_ROM);
__SEG_END_DEF(SHADOW_ROM);
__SEG_SIZE_DEF(SHADOW_ROM);
/*************************************************************************************/
static void CopyCodeToRAM(void)
{
/* Variable Declarations */
uchar *Src;
uchar *Dst;
uint SegSize;
uint x;
/* Begin Function CopyCodeToRAM() */
Src = (uchar *)__SEG_START_REF(SHADOW_ROM); /* RAM code resides in Flash */
Dst = (uchar *)0x001000; /* copied to RAM */
SegSize = (uint)__SEG_SIZE_REF(SHADOW_ROM);
for (x = 0; x < SegSize; x++) /* just copy a byte at a time */
*Dst++ = *Src++;
} /* end CopyCodeToRAM */
/*************************************************************************************/
The macros are used to obtain the SHADOW_ROM section start address and its size from linker defined symbols.
Finally, you no longer need the function pointers FTMRZ_Erase_Flash_RAM and FTMRZ_Prog_Phrase_RAM to call the functions. instead you can directly reference the two functions that were copied into RAM via their names i.e. FTMRZ_Erase_Flash(); and FTMRZ_Prog_Phrase(); because the code was linked to their relocated addresses in RAM.
Hopefully I've not missed describing any of the modifications I made to your project, but the modified project is attached. I couldn't completely test this out, but I could do enough via the debugger in a target system to see that the functions were being called in RAM.
Hope this helps.
Best Regards,
Gordon