Swap word order on SPI XiP flash

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Swap word order on SPI XiP flash

      When programming QSPI serial flash, the word order is swapped, and execution fails (core hardfault).

      The device is an NXP Kinetis K8x (K81/K81 family) MCU part, with a Micron or Cypress 128Mb serial QSPI flash part. The MCU has a QSPI peripheral with XiP capability, for which the default configuration is 64-bit Little-endian. When using the external flash as a data device, the 32-bit word order is consistent and correct. However, when using the external flash for executable code, the word order of the instructions is swapped.

      Expected
      ADDR 0004 [byte7][byte6][byte5][byte4]
      ADDR 0000 [byte3][byte2]byte1][byte0]

      Loaded:
      ADDR 0004 [byte3][byte2]byte1][byte0]
      ADDR 0000 [byte7][byte6][byte5][byte4]

      Now, if I set the QSPI peripheral at 32-bit Little endian, the the J-Link programmed code runs. However, data reads now have the each 32-bit word pair swapped.

      Sanity check: I manually swapped the word order of the external function in the Intel Hex file, and then programmed the flash, and everything ran perfectly. (Note that I did not touch the word order of code targeted at the main, internal flash)

      What's going on here? Can the J-Link be set to swap words? Should I be looking at the GNU compiler/linker/objcopy to fix this? Any ideas are welcome.
    • Hello,

      Thank you for your inquiry.
      Such an issue is not known to us.
      J-Link will store data exactly as specified in your binary or hex you are trying to program.
      Is the data also swapped in the binary/hex that gets output by your Toolchain?
      Which target device are you trying to debug exactly?
      Is it on an eval board or custom hardware?

      Best regards,
      Nino
      Please read the forum rules before posting: Forum Rules

      Keep in mind, this is not a support forum. Its main purpose is user to user interaction.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support contact us per e-mail.
      The following contact form can be used for this: Contact Us

    • Hi Nino,

      It appears that the data is stored exactly as specified in the ihex file, and is not swapped in the toolchain. I appears that the problem occurs with direct memory-mapped reads: pairs of 32-bit words are swapped between reading from flash, and their arrival in the instruction queue. I have tried this on both my custom board (NXP MK81), and an eval board (NXP FRDM-K82F). NXP are investigating: I will let you know what they find.

      Kind regards,
      Denis
    • New

      In the meantime I am trying to find a solution using a JLink Script, triggered from the GDB. The script runs but does not change the register as expected.

      C Source Code

      1. /*********************************************************************
      2. *
      3. * InitTarget
      4. */
      5. int HandleBeforeFlashProg(void) {
      6. U32 QSPI_MCR_BASE;
      7. U32 QSPI_MCR_DATA;
      8. U32 QSPI_MCR_64LE;
      9. int r;
      10. Report("J-Link script: NXP_MK8x_QSPI.JLinkScript");
      11. QSPI_MCR_BASE = 0x400DA000; // Address of QuadSPI0_MCR Register on K8x MCU
      12. QSPI_MCR_64LE = 0x0000000C; // 64LE: bits[3:2] = 3
      13. QSPI_MCR_DATA = JLINK_MEM_ReadU32(QSPI_MCR_BASE);
      14. JLINK_SYS_Report1("J-Link script: Reading QSPI->MCR: ", QSPI_MCR_DATA);
      15. QSPI_MCR_DATA = QSPI_MCR_DATA | QSPI_MCR_64LE;
      16. JLINK_SYS_Report1("J-Link script: Writing QSPI->MCR: ", QSPI_MCR_DATA);
      17. r = JLINK_MEM_WriteU32(QSPI_MCR_BASE, QSPI_MCR_DATA);
      18. if (r <0) {
      19. JLINK_SYS_Report("J-Link script: !!Unable to set QuadSPI_MCR to 64bit Little-endian!!");
      20. }
      21. else {
      22. JLINK_SYS_Report("J-Link script: QuadSPI_MCR set to 64bit Little-endian");
      23. }
      24. return r;
      25. }
      Display All

      output:
      ...
      Verify method "Programmed sectors, fastest method" is not supported for this device.
      Changed to "Programmed sectors using read back"
      J-Link script: NXP_MK8x_QSPI.JLinkScript
      J-Link script: Reading QSPI->MCR: 0xFFFFFFFF <<< This is not correct - looks like the register read failed
      J-Link script: Writing QSPI->MCR: 0xFFFFFFFF
      J-Link script: QuadSPI_MCR set to 64bit Little-endian
      J-Link: Flash download: Bank 0 @ 0x00000000
      J-Link: Flash download: Bank 1 @ 0x68000000