I'm not really sure what you are doing. Here I have simple piece of code for unlock, erase and program:
// step1. unlock all blocks (for simplicity)
C55FMC.LOCK0.R = 0;
C55FMC.LOCK1.R = 0;
C55FMC.LOCK2.R = 0;
C55FMC.LOCK3.R = 0;
// step2. erase the large block 31 (0x00FC0000 - 0x00FFFFFF)
C55FMC.MCR.B.ERS = 1;
C55FMC.SEL2.R = 0x80000000; // select the large block 7
*(unsigned int*)0x00FC0000 = 0xFFFFFFFF; //interlock write
C55FMC.MCR.B.EHV = 1;
while(C55FMC.MCR.B.DONE == 0);
C55FMC.MCR.B.EHV = 0;
C55FMC.MCR.B.ERS = 0;
// step3. program data
C55FMC.MCR.B.PGM = 1;
*(unsigned int*)0x00FC0000 = 0xAABBCCDD; //interlock write
*(unsigned int*)0x00FC0004 = 0x11223344;
C55FMC.MCR.B.EHV = 1;
while(C55FMC.MCR.B.DONE == 0);
C55FMC.MCR.B.EHV = 0;
C55FMC.MCR.B.PGM = 0;
Not sure why SPI is mentioned. You can use SPI only to get some command from outside world that someone wants to perform flash operations and your application can execute some code like the code above.
And again - make sure that data cache is disabled or invalidated to see the correct result.
Regards,
Lukas