lpcware

SPIFI Command Mode to Memory Mode

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by ArriaLive on Wed Aug 27 01:06:38 MST 2014
I discovered last week that when I ran XIP code over SPIFI during a debug session, I could pretty much get full quad mode at 104MHz.  But outside of the debugger, SPIFI was running far slower--in SDR mode, and 50MHz was the max I could squeeze out of it.  Performance dropped from 52MB/s to 6MB/s.

I discovered that this was because the debugger puts the flash in quad mode, but without the debugger, my code was not putting it in quad high-performance mode.  Makes sense.

So, I've spent the last week trying to get the flash into high performance mode, but I continue to fail at that effort.  The problem is that when I put the SPIFI interface into memory mode, the memory essentially disappears.  Here's an example of a simple routine:

Memory at 0x14000000 at start of routine:

0x14000000 - 10020000 140004FD 1400018D 14000191 14000195 14000199 1400019D 00000000 00000000 00000000 
0x14000028 - 00000000 140001A1 140001A5 00000000 140001A9 14009C25 140001B1 140001B1 10000079 00000000 
0x14000050 - 140001B1 1000011D 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 
0x14000078 - 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1 140001B1

clearly showing what appears to be a vector table.  Then I execute the following sequence simply going from memory mode to command mode and back again:

------------------
__disable_irq(); // Disable IRQs

    SCnSCB->ACTLR &= ~2; // disable Cortex write buffer to avoid exceptions when switching back to SPIFI for execution

tempmemcmd = LPC_SPIFI->MEMCMD;

    /* check for memory mode.  If not there, reset */
    if (LPC_SPIFI->STAT & SPIFI_STAT_MCINIT) { // In memory mode? MCINIT bit is bit 0

    LPC_SPIFI->STAT = SPIFI_STAT_RESET; // Go to command mode
        while(LPC_SPIFI->STAT & SPIFI_STAT_RESET); // wait for reset to complete
    }

LPC_SPIFI->MEMCMD = tempmemcmd;
-------------------

At the end, all 8 SPIFI registers look EXACTLY as they did at the beginning.  After the reset, the MCINIT bit is 0 as expected.  After the MEMCMD, the MCINIT bit goes to 1 as expected.  All the registers look right, but the memory itself does not.  Here's what that same segment of flash memory looks like at the end of that short sequence:

0x14000000 - 00000000 00000000 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC 
0x14000028 - CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
0x14000050 - CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
0x14000078 - CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC

Obviously something is wrong.  All the flash data is essentially gone.  Any attempt to XIP anywhere in flash after this, of course, creates a hard-fault exception.

I must be missing something somewhere.  Why is the flash going away?  Am I missing a register setting or some other requirement?  I've scoured the documentation for both the processor and flash.  I've searched the forums and googled everything I could think of.  But I have not found an answer.

Anyone have any ideas?  Thank you in advance for the guidance!

Processor: LPC4330
Flash:  Spansion S25FL256S

EdA

Outcomes