LPCXpresso 8.2.2 executes differently than 7.4

cancel
Showing results for 
Search instead for 
Did you mean: 

LPCXpresso 8.2.2 executes differently than 7.4

463 Views
edarrington
Contributor II

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:

Capture 7.4.PNG

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

Capture 8.2.2.PNG

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?

0 Kudos
2 Replies

246 Views
lpcxpresso_supp
NXP Employee
NXP Employee

First of all, I'm not an expert of the SPIFI interface, so can't comment on your accesses to the SPIFI peripheral.

But the obvious difference is that the compiler is several versions newer - so its possible that a change in the compiled code is triggering your issue. What optimisation level are you building with Debug/-O0, Release/-Os or something else?

I assume that this code is intended to be run from RAM - but can you confirm this is actually the case? What is the value of the PC register when you actually hit your breakpoint? You might also want to make your breakpoint volatile to prevent the compiler

Something else you might want to try is to debug by single stepping through the code, but at the instruction level rather than source level : Disassembly View and instruction level debugging . 

It might also be interesting to see the debug log from your debug connections - from both LPCXpresso IDE 7.4 and 8.2.2 : The Debug Log , as well as the map files generated by the linker from both versions.

Regards,

LPCXpresso Support

0 Kudos

246 Views
edarrington
Contributor II

With apologies for the delay in responding, I have resolved this issue.  The base problem is that the flash driver used with LPCXpresso 7.4 left the flash memory in a state (when loading code into flash) than the 8.2.2 version did.  This problem occurred in my case when using the Spansion (Cypress) external flash memory chips, along with the dedicated driver in 7.4 and the Generic driver in 8.2.2.  

Each flash memory chip has some unique settings for putting the flash into quad read mode versus serial mode, and apparently the newer 8.2.2 version of the flash drivers did it differently than the older 7.4 version did.

The Generic driver used to load code, then, puts the flash in a state my code was not expecting.  My SPIFI code, therefore, when setting back to memory mode, ended up in a state where flash could no longer be read reliably.

Through much trial and error I was able to make all the code work, and was able to write a driver for the our newer flash memory as well.  This is not a process for the faint of heart, and took some time to resolve.  Once done, it seems to work pretty well.

0 Kudos