AnsweredAssumed Answered

LPCXpresso 8.2.2 executes differently than 7.4

Question asked by Ed Arrington on Jun 13, 2017
Latest reply on Jun 30, 2017 by Ed Arrington

My company has been sticking with version 7.4 of LPCXpresso for several years for the sake of development stability.  Now, due to a change in flash memory, we need to move to a more recent version of LPCXpresso to be able to create a customer flash driver.  However, the transition is not going well.  Identical code running on 7.4 and 8.2.2 has different results.  The tests below were done using the same LPCXpresso flash driver (not our own), on an older board that has worked well for several years with the existing driver.  When initializing the flash in our own application, however, the results are different.  In 8.2.2, the SPIFI will not return to memory mode.

 

Here is the code segment:

 

#define BREAKPOINT __asm__("BKPT")

 

RAM2 void SPIFI_memmode(LPC_SPIFI_T *spifi) {

 

   /* dummy address value for first read */
   spifi->ADDR = 0x0;

 

   /* high speed mode uses this pattern. The 0xA in the high order nibble is required to stay in
   * high perf (no opcode) mode. All other bits are don't care */
   spifi->DATINTM = 0xA0;

 

   /* send the CMD for memory read. This puts the flash memory in High Performance (no opcode) mode for subsequent reads
   * This is required because the flash needs at least one real opcode before going into high performance (no opcode) mode
   * We need to include the address because we want the intermediate (mode) byte to be sent, informing the flash that subsequent
   * accesses will not use the opcode, but will just send the address */
   spifi->CMD = SPIFI_CMD_OPCODE(OPCODE_QIOR) // opcode 0xeb Quad IO High Performance Read for Spansion
      | SPIFI_CMD_DATALEN(0)
      | SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE)
      | SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP_3ADDRESS)
      | SPIFI_CMD_INTER(0x3) // 3 intermediate data bytes;
      ;

   

   /* Wait for command to complete */
   while(spifi->STAT & SPIFI_STAT_CMD);

 

   /* Now we send the opcode to memcmd to put SPIFI in memory mode, with no opcode required since we're in high-performance mode */
   spifi->MEMCMD = SPIFI_CMD_OPCODE(OPCODE_QIOR) // opcode 0xeb Quad IO High Performance Read for Spansion
      | SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_SERIAL_OPCODE)
      | SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_NOOP_3ADDRESS)
      | SPIFI_CMD_INTER(0x3) // 3 intermediate data bytes;
      ;
   BREAKPOINT;

}

This is the first code to run once the startup code hands off control to main().

This identical code is being run on both versions.  Both 8.2.2 and 7.4 are pointing to the identical directory, so we know that the raw code is the same.  The code has been compiled "clean" on both sides.  This code uses the default linker script in both cases.

 

Now, when the breakpoint hits, in 7.4 we see this in memory.  This is pointing the the SPIFI registers:

On the other hand, when running the IDENTICAL code under 8.2.2, we get the following memory report in the SPIFI registers:

Notice that in 7.4 the MSB of the SPIFI config register (at 0x40003000) are different that the same bits in 8.2.2.  Also note the byte order difference in the second word, presumably the CMD register.

 

Both samples use the same code with the same LPC library definition of LPC_SPIFI_T.  When running in 7.4, the application runs as expected.  In 8.2.2 we crash immediately when the next XIP code in flash attempts to execute, because the SPIFI has not changed to memory mode.

 

FYI, our debug probe is LPC-Link2 in DFU mode.

 

Why are the results different just by changing the version of the application?  Did I miss a setting somewhere?

Outcomes