RT1050 - Debugging with QSPI flash on secondary pinmux

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RT1050 - Debugging with QSPI flash on secondary pinmux

Jump to solution
7,087 Views
dmarks_ls
Senior Contributor I

TL;DR - We can't seem to download and debug an RT1050 program image to a board that has a QSPI flash attached to the secondary FlexSPI pinmux location.

We've constructed a custom board based on the RT1050 (MIMXRT1052CVJ5B).  Because of how many serial I/O ports we had to allocate, we did not use an octal HyperFlash like that on the EVKB; rather, we connected a QSPI flash (S25FL256L) to the secondary pinmux location, as so:

QSPIFLEXSPIGPIOBall
CS*FLEXSPI_A_SS0_BGPIO_B1_15J14
SCLKFLEXSPI_A_SCLKGPIO_B1_14G12
D3FLEXSPI_A_DATA3GPIO_B1_10L13
D2FLEXSPI_A_DATA2GPIO_B1_11J13
D1FLEXSPI_A_DATA1GPIO_B1_12H12
D0FLEXSPI_A_DATA0GPIO_B1_13H11

We also replicated the configuration DIP switches that are present on the EVKB.  Referring to Table 8-9 of the RT1050 manual, I could see that BOOT_CFG2[2:0] (i.e. BOOT_CFG[10:8]) needed to be "111" for "QSPI device supports 3B read by default (on secondary pinmux option)", not "010" for "HyperFlash 1.8V".  So I set the DIP switches to "0000 0011 0110" to select Flash Type 111 and Boot Type 10 (internal boot).  And it appears that I've set the DIP switches correctly, because if I reset the processor, I see this on the QSPI pins:

rt1050_logic_qspi_secondary_pinmux.png

My Logic pod isn't fast enough to capture the actual data that's being transmitted (nor can it decode QSPI), but I can see three bursts... the first two are about 3.7 us each, and the big one is about 259 us long.

The debug pod (SEGGER J-Link Pro) connects OK with the CPU; there was some initial confusion over what debug mode to use, but we now have SWD selected.  When I try to program and download an image, the SEGGER four-bar programming window appears, it gets to 25% compare a touch slowly, then 50%, then the window disappears:

mcux_segger_flash_download.png

Then the debugger lands at address 0x20b4f2 (the actual address for any given run is somewhat random, I got 0x20d136 another time):

mcux_break_at_address.png

And you pretty much can't do anything at this point.  The addresses clearly reside inside the ROM region, so presumably the RT1050 was not able to boot successfully and remained in its ROM program.

Here's what I see on my Logic probe while launching the debug session:

rt1050_logic_qspi_debug_start.png

That big burst in the middle there is a whole bunch of transfers, each lasting about 259 us and spaced apart every 6-7 ms.  So, any ideas what we're doing wrong?  I certainly can't rule out a hardware issue, but it looks like the signals between the CPU and the QSPI flash are OK.  Maybe one has to do some additional configuration of the J-Link debug launch.  Where should I start?

Tags (2)
1 Solution
5,554 Views
dmarples
Contributor IV

David,

Sorry if I confused matters, was trying to help. I went through a _lot_ of pain getting this configuration running, so I'd like to help a fellow sufferer

JLink certainly can program a blank flash on the secondary pinmux, that is (now!) what I do all of the time. I'm on 1021, but I can't imagine there are differences.  Given that your CPU is trying to access the flash I would be inclined to suspect you've got the various initialisation tables a bit wrong (or, more probably, MCUX has, since I don't think you generate them manually in a MCUX configuration).

I'm running NuttX and the start of my flash looks like this;

60000000 A __boot_hdr_start__
60000000 R flash_config
60001000 A __boot_hdr_conf__
60001000 R g_image_vector_table
60001020 R g_boot_data
60001030 A __boot_hdr_end__
60002000 A _stext
60002000 T _vectors

...and the various data in each of those tables is as follows;

000000 4346 4246 0400 5601 0000 0000 0300 0003
000010 0001 0000 0401 0000 0040 0000 0000 0000
000020 0000 0000 0000 0000 0000 0000 0000 0000
<SNIP>
001000 00d1 4120 2000 6000 0000 0000 0000 0000
001010 1020 6000 1000 6000 0000 0000 0000 0000
001020 0000 6000 ffff 1f7f 0000 0000 ffff ffff
001030 ffff ffff ffff ffff ffff ffff ffff ffff

The source that I build those tables from is;

__attribute__((section(".boot_hdr.conf")))
const struct flexspi_nor_config_s flash_config =
{
  .mem_config =
  {
    .tag                    = FLEXSPI_CFG_BLK_TAG,
    .version                = FLEXSPI_CFG_BLK_VERSION,
    .read_sample_clksrc     = FLASH_READ_SAMPLE_CLK_LOOPBACK_INTERNELLY,
    .cs_hold_time           = 3u,
    .cs_setup_time          = 3u,
    .device_mode_cfg_enable = true,    
    .device_mode_seq.seq_num= 1,
    .device_mode_seq.seq_id = 4,     /* These commands set the Quad bit */ 
    .device_mode_arg        = 0x40,  /* on the flash to drive 4 pins.   */
    .device_type            = FLEXSPI_DEVICE_TYPE_SERIAL_NOR,
    .sflash_pad_type        = SERIAL_FLASH_4PADS,    
    .serial_clk_freq        = FLEXSPI_SERIAL_CLKFREQ_100MHz,
    .sflash_a1size          = 8u * 1024u * 1024u,
    .data_valid_time        = {16u, 16u},
    /* .controller_misc_option = (1 << FLEXSPIMISC_OFFSET_PAD_SETTING_OVERRIDE_EN), */
    /* .cspad_setting_override =   1|(1<<3)|(3<<6),  */
    /* .sclkpad_setting_override = (7<<3)|(3<<6),  */
    /* .datapad_setting_override = (2<<3)|(3<<6),  */
    /* .dqspad_setting_override = 0, */

    .lookup_table           =
    {
      /* 0 - Quad Input/output read sequence - with optimised XIP support */
      [0]=FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
      [1]=FLEXSPI_LUT_SEQ(MODE8_SDR, FLEXSPI_4PAD, 0xA0, DUMMY_SDR, FLEXSPI_4PAD, 0x04),
      [2]=FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_4PAD, 0x04, JMP_ON_CS, 0, 1),

      /* 1 - Read Status */
      [1*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01),
    
      /* 3 - Write Enable */
      [3*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, 0, 0),
    
      /* 4 - Write status */
      [4*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x1), 

      /* 5 - Erase Sector */
      [5*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD7, RADDR_SDR, FLEXSPI_1PAD, 0x18),
      
      /* 9 - Page Program */
      [9*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),
      [9*4+1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x8, STOP, FLEXSPI_1PAD, 0x0),
    
      /* 11 - Chip Erase */
      [11*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xC7, STOP, FLEXSPI_1PAD, 0x0),
    },
  },
  
  .page_size                = 256u,
  .sector_size              = 4u * 1024u,
  .blocksize                = 32u * 1024u,
  .is_uniform_blocksize     = false,
};

__attribute__((section(".boot_hdr.ivt")))
const struct ivt_s g_image_vector_table =
{
  IVT_HEADER,                         /* IVT Header */
  0x60002000,                         /* Image  Entry Function */
  IVT_RSVD,                           /* Reserved = 0 */
  (uint32_t)DCD_ADDRESS,              /* Address where DCD information is stored */
  (uint32_t)BOOT_DATA_ADDRESS,        /* Address where BOOT Data Structure is stored */
  (uint32_t)&g_image_vector_table,    /* Pointer to IVT Self (absolute address) */
  (uint32_t)CSF_ADDRESS,              /* Address where CSF file is stored */
  IVT_RSVD                            /* Reserved = 0 */
};

__attribute__((section(".boot_hdr.boot_data")))
const struct boot_data_s g_boot_data =
{
  FLASH_BASE,                         /* boot start location */
  (FLASH_END - FLASH_BASE),           /* size */
  PLUGIN_FLAG,                        /* Plugin flag*/
  0xFFFFFFFF                          /* empty - extra data word */
};

Drop me a note if you want an image to just try burning into the chip to see if it will boot from it...you should be able to do that from JLinkExe which would at least put to bed any concern over hardware issues.

Regards

DAVE

View solution in original post

27 Replies
5,274 Views
dmarks_ls
Senior Contributor I

Hi kerryzhou‌,

Well, good news and bad news.  Bad news, I've given up on making this Cypress S25FL256S flash work.  I'm simply not equipped or prepared to go into an exhaustive analysis of what's wrong with my present setup.

Good news, we got a couple of ISSI IS25LP064A chips in, I replaced the Cypress with the ISSI on one of our prototypes, built my app (with a properly modified DCD header), dialed up the correct settings in the MCU Config Tool, and the tool programmed the board successfully.  I then hacked my SEGGER XML file (still annoyed that's a step), downloaded via the debugger, and whaddaya know, the damn thing actually works.  For reference, here is how I modified evkbimxrt1050_flexspi_nor_config.c (following exactly what dmarples‌ laid out):

/* Width of flash addresses (either 24 or 32). */
#define QSPI_ADDR_WIDTH   24u

#ifdef USE_QSPI
const flexspi_nor_config_t qspi_config = {
    .memConfig = {
        .tag                = FLEXSPI_CFG_BLK_TAG,
        .version            = FLEXSPI_CFG_BLK_VERSION,
        .readSampleClkSrc   = kFlexSPIReadSampleClk_LoopbackInternally,
        .csHoldTime         = 3u,
        .csSetupTime        = 3u,
        /* This defines the sequence to use to set the QUAD bit.
         * Command 0x01 writes the status register and sets bit 6 (0x40).
         * SR = 0x40 (bit 6 = QE Quad Enable, all other bits to 0) */
        .deviceModeCfgEnable  = true,
        .deviceModeSeq.seqNum = 1,
        .deviceModeSeq.seqId  = 4,
        .deviceModeArg        = 0x40,
        /* Device geometry, I/O, and speed. */
        .deviceType    = kFlexSpiDeviceType_SerialNOR,
        .sflashPadType = kSerialFlash_4Pads,
        .serialClkFreq = kFlexSpiSerialClk_100MHz,
        .sflashA1Size  = 8u * 1024u * 1024u,
        .dataValidTime = {16u, 16u},
        /* Lookup table for flash commands for this device.  Up to 8 instructions
         * can be defined for each LUT table location.  Each instruction is 16 bits,
         * and the data structure organizes them as 32-bit words (for some reason). */
        .lookupTable = {
            /* 0 - Quad Input/output read sequence - with optimized XIP support */
            [0*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0xEB,
                                        RADDR_SDR,  FLEXSPI_4PAD, QSPI_ADDR_WIDTH),
            [0*4+1]   = FLEXSPI_LUT_SEQ(MODE8_SDR,  FLEXSPI_4PAD, 0xA0, // 2 dummy cycles
                                        DUMMY_SDR,  FLEXSPI_4PAD, 4),   // 4 dummy cycles
            [0*4+2]   = FLEXSPI_LUT_SEQ(READ_SDR,   FLEXSPI_4PAD, 4,
                                        JMP_ON_CS,  FLEXSPI_1PAD, 1),
            /* 1 - Read Status */
            [1*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x05,
                                        READ_SDR,   FLEXSPI_1PAD, 1),   // Read 1 byte
            /* 3 - Write Enable */
            [3*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x06,
                                        STOP,       FLEXSPI_1PAD, 0),
            /* 4 - Write status */
            [4*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x01,
                                        WRITE_SDR,  FLEXSPI_1PAD, 1),   // Write 1 byte
            /* 5 - Erase Sector */
            [5*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0xD7, // Sector Erase, 1-bit
                                        RADDR_SDR,  FLEXSPI_1PAD, QSPI_ADDR_WIDTH),
            /* 9 - Page Program */
            [9*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x02,
                                        RADDR_SDR,  FLEXSPI_1PAD, QSPI_ADDR_WIDTH),
            [9*4+1]   = FLEXSPI_LUT_SEQ(WRITE_SDR,  FLEXSPI_1PAD, 0x08, // any non-zero value
                                        STOP,       FLEXSPI_1PAD, 0),
            /* 11 - Chip Erase */
            [11*4+0]  = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0xC7,
                                        STOP,       FLEXSPI_1PAD, 0x0),
        },
    },
    .pageSize           = 256u,
    .sectorSize         = 4u * 1024u,
    .blockSize          = 32u * 1024u,
    .isUniformBlockSize = false,
};
#else
const flexspi_nor_config_t hyperflash_config = {
[...]
};
#endif‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

It also turns out that because of some changes to the system over the past couple of months, it will be possible in Rev. B of our board to shuffle some things around and get an 8-bit HyperFlash connected to the primary pinmux location, so we won't have any of these issues to deal with in the future.  So at least we proved that yes, we can boot off the secondary pinmux location, even if we weren't able to do it with the QSPI flash we originally selected.  Thanks everyone for all the assistance.

5,274 Views
amwilhite
Contributor III

I had been using the flash config structure referenced inthis thread on the evaluation board, and was able to debug using the JLink after modifying the JLinkDevices.xml file.

Our custom boards that use the IS25WP064A Quad SPI Flash arrived recently, and I had been having no luck getting debugging with the JLink working with them. After double checking the BOOT_MODE/BOOT_CONFIG settings several times, I changed my flash config structure to this one, and JLink debugging started working immediately. I'm not sure what difference exists between the boards (they were designed to mimic the evaluation board Quad SPI flash layout) or which setting "made it work," but I'm glad this fixed it.

Thanks for the help!

5,555 Views
dmarples
Contributor IV

David,

Sorry if I confused matters, was trying to help. I went through a _lot_ of pain getting this configuration running, so I'd like to help a fellow sufferer

JLink certainly can program a blank flash on the secondary pinmux, that is (now!) what I do all of the time. I'm on 1021, but I can't imagine there are differences.  Given that your CPU is trying to access the flash I would be inclined to suspect you've got the various initialisation tables a bit wrong (or, more probably, MCUX has, since I don't think you generate them manually in a MCUX configuration).

I'm running NuttX and the start of my flash looks like this;

60000000 A __boot_hdr_start__
60000000 R flash_config
60001000 A __boot_hdr_conf__
60001000 R g_image_vector_table
60001020 R g_boot_data
60001030 A __boot_hdr_end__
60002000 A _stext
60002000 T _vectors

...and the various data in each of those tables is as follows;

000000 4346 4246 0400 5601 0000 0000 0300 0003
000010 0001 0000 0401 0000 0040 0000 0000 0000
000020 0000 0000 0000 0000 0000 0000 0000 0000
<SNIP>
001000 00d1 4120 2000 6000 0000 0000 0000 0000
001010 1020 6000 1000 6000 0000 0000 0000 0000
001020 0000 6000 ffff 1f7f 0000 0000 ffff ffff
001030 ffff ffff ffff ffff ffff ffff ffff ffff

The source that I build those tables from is;

__attribute__((section(".boot_hdr.conf")))
const struct flexspi_nor_config_s flash_config =
{
  .mem_config =
  {
    .tag                    = FLEXSPI_CFG_BLK_TAG,
    .version                = FLEXSPI_CFG_BLK_VERSION,
    .read_sample_clksrc     = FLASH_READ_SAMPLE_CLK_LOOPBACK_INTERNELLY,
    .cs_hold_time           = 3u,
    .cs_setup_time          = 3u,
    .device_mode_cfg_enable = true,    
    .device_mode_seq.seq_num= 1,
    .device_mode_seq.seq_id = 4,     /* These commands set the Quad bit */ 
    .device_mode_arg        = 0x40,  /* on the flash to drive 4 pins.   */
    .device_type            = FLEXSPI_DEVICE_TYPE_SERIAL_NOR,
    .sflash_pad_type        = SERIAL_FLASH_4PADS,    
    .serial_clk_freq        = FLEXSPI_SERIAL_CLKFREQ_100MHz,
    .sflash_a1size          = 8u * 1024u * 1024u,
    .data_valid_time        = {16u, 16u},
    /* .controller_misc_option = (1 << FLEXSPIMISC_OFFSET_PAD_SETTING_OVERRIDE_EN), */
    /* .cspad_setting_override =   1|(1<<3)|(3<<6),  */
    /* .sclkpad_setting_override = (7<<3)|(3<<6),  */
    /* .datapad_setting_override = (2<<3)|(3<<6),  */
    /* .dqspad_setting_override = 0, */

    .lookup_table           =
    {
      /* 0 - Quad Input/output read sequence - with optimised XIP support */
      [0]=FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
      [1]=FLEXSPI_LUT_SEQ(MODE8_SDR, FLEXSPI_4PAD, 0xA0, DUMMY_SDR, FLEXSPI_4PAD, 0x04),
      [2]=FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_4PAD, 0x04, JMP_ON_CS, 0, 1),

      /* 1 - Read Status */
      [1*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01),
    
      /* 3 - Write Enable */
      [3*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, 0, 0),
    
      /* 4 - Write status */
      [4*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x01, WRITE_SDR, FLEXSPI_1PAD, 0x1), 

      /* 5 - Erase Sector */
      [5*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD7, RADDR_SDR, FLEXSPI_1PAD, 0x18),
      
      /* 9 - Page Program */
      [9*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),
      [9*4+1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x8, STOP, FLEXSPI_1PAD, 0x0),
    
      /* 11 - Chip Erase */
      [11*4] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xC7, STOP, FLEXSPI_1PAD, 0x0),
    },
  },
  
  .page_size                = 256u,
  .sector_size              = 4u * 1024u,
  .blocksize                = 32u * 1024u,
  .is_uniform_blocksize     = false,
};

__attribute__((section(".boot_hdr.ivt")))
const struct ivt_s g_image_vector_table =
{
  IVT_HEADER,                         /* IVT Header */
  0x60002000,                         /* Image  Entry Function */
  IVT_RSVD,                           /* Reserved = 0 */
  (uint32_t)DCD_ADDRESS,              /* Address where DCD information is stored */
  (uint32_t)BOOT_DATA_ADDRESS,        /* Address where BOOT Data Structure is stored */
  (uint32_t)&g_image_vector_table,    /* Pointer to IVT Self (absolute address) */
  (uint32_t)CSF_ADDRESS,              /* Address where CSF file is stored */
  IVT_RSVD                            /* Reserved = 0 */
};

__attribute__((section(".boot_hdr.boot_data")))
const struct boot_data_s g_boot_data =
{
  FLASH_BASE,                         /* boot start location */
  (FLASH_END - FLASH_BASE),           /* size */
  PLUGIN_FLAG,                        /* Plugin flag*/
  0xFFFFFFFF                          /* empty - extra data word */
};

Drop me a note if you want an image to just try burning into the chip to see if it will boot from it...you should be able to do that from JLinkExe which would at least put to bed any concern over hardware issues.

Regards

DAVE

5,275 Views
dmarks_ls
Senior Contributor I

Hi dmarples‌,

I see what you're on about with editing the boot header configuration... that does have to be customized to match the flash device that's in use on the board.  Can you tell me what flash device you have on your RT1021 board?  I need to reconcile some of what's in your source code with your device's datasheet. so I can better understand how to modify my code for our flash device.  We're using a Cypress S25FL256L (datasheet), and I can see that its geometry and command set is slightly different from what you have defined.

David R.

0 Kudos
5,275 Views
dmarples
Contributor IV

I'm using the same devices as on the Eval Board, IS25LP064A. It's a while since I made the changes but IIRC you don't need _all_ of the entries in the boot header to bring it up (once I'd figured out the structure of the boot header, then it was easier to put them all in for the case I might need them later).  I would recommend dropping one of these chips onto your board to remove a variable, then working back to your flash device.

Regards

DAVE

5,274 Views
dmarks_ls
Senior Contributor I

So your code was quite helpful in helping me understand what exactly is going on in the boot header.  I can see how the code conforms to the ISSI IS25LP064, and also what needs to change for my Cypress S25FL256 device.  Notably, the Cypress part has four status registers (well, one status and three configuration registers), and the QUAD enable bit is in bit 1 of the second register, not bit 3 of the first.  So right now this is my boot header code:

/* Width of flash addresses (either 24 or 32). */
#define QSPI_ADDR_WIDTH   24u

#ifdef USE_QSPI
const flexspi_nor_config_t qspi_config = {
    .memConfig = {
        .tag                = FLEXSPI_CFG_BLK_TAG,
        .version            = FLEXSPI_CFG_BLK_VERSION,
        .readSampleClkSrc   = kFlexSPIReadSampleClk_LoopbackInternally,
        .csHoldTime         = 3u,
        .csSetupTime        = 3u,
        /* This defines the sequence to use to set the QUAD bit.
         * Command 0x01 writes up to four registers - SR1V, CR1V, CR2V, CR3V.
         * SR1V = 0x00 (no protection)
         * CR1V = 0x20 (bit 1 = QUAD enable, all other bits to 0)
         * CR2V = 0x60 (defaults -- high driver impedance, QPI off, 24-bit addresses)
         * CR3V = 0x78 (defaults -- 64 byte wrap, wrap disabled, 8 read dummy cycles) */
        .deviceModeCfgEnable  = true,
        .deviceModeSeq.seqNum = 1,
        .deviceModeSeq.seqId  = 4,
        .deviceModeArg        = 0x00026078,
        /* Device geometry, I/O, and speed. */
        .deviceType    = kFlexSpiDeviceType_SerialNOR,
        .sflashPadType = kSerialFlash_4Pads,
        .serialClkFreq = kFlexSpiSerialClk_100MHz,
        .sflashA1Size  = 32u * 1024u * 1024u,
        .dataValidTime = {16u, 16u},
        /* Lookup table for flash commands for this device.  Up to 8 instructions
         * can be defined for each LUT table location.  Each instruction is 16 bits,
         * and the data structure organizes them as 32-bit words (for some reason). */
        .lookupTable = {
            /* 0 - Quad Input/output read sequence - with optimized XIP support */
            [0*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0xEB,
                                        RADDR_SDR,  FLEXSPI_4PAD, QSPI_ADDR_WIDTH),
            [0*4+1]   = FLEXSPI_LUT_SEQ(MODE8_SDR,  FLEXSPI_4PAD, 0xA0, // 2 dummy cycles
                                        DUMMY_SDR,  FLEXSPI_4PAD, 4),   // 4 dummy cycles
            [0*4+2]   = FLEXSPI_LUT_SEQ(READ_SDR,   FLEXSPI_4PAD, 4,
                                        JMP_ON_CS,  FLEXSPI_1PAD, 1),
            /* 1 - Read Status */
            [1*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x05,
                                        READ_SDR,   FLEXSPI_1PAD, 1),   // Read 1 byte
            /* 3 - Write Enable */
            [3*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x06,
                                        STOP,       FLEXSPI_1PAD, 0),
            /* 4 - Write status */
            [4*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x01,
                                        WRITE_SDR,  FLEXSPI_1PAD, 4),   // Write 4 bytes
            /* 5 - Erase Sector */
            [5*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0xD8, // Block Erase
                                        RADDR_SDR,  FLEXSPI_1PAD, QSPI_ADDR_WIDTH),
            /* 9 - Page Program */
            [9*4+0]   = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0x02,
                                        RADDR_SDR,  FLEXSPI_1PAD, QSPI_ADDR_WIDTH),
            [9*4+1]   = FLEXSPI_LUT_SEQ(WRITE_SDR,  FLEXSPI_1PAD, 0x08,
                                        STOP,       FLEXSPI_1PAD, 0),
            /* 11 - Chip Erase */
            [11*4+0]  = FLEXSPI_LUT_SEQ(CMD_SDR,    FLEXSPI_1PAD, 0xC7,
                                        STOP,       FLEXSPI_1PAD, 0x0),
        },
    },
    /* Pretend that our sectors (4KB) are as big as our 64KB blocks. */
    .pageSize           = 256u,
    .sectorSize         = 64u * 1024u,
    .blockSize          = 64u * 1024u,
    .isUniformBlockSize = true,
};
#else
const flexspi_nor_config_t hyperflash_config = {
[...]
};
#endif // USE_QSPI

I'm not sure if this is completely correct, but it seems that the boot utility liked it enough to flash my SREC image to my board.  I think what I probably need to do now is verify that I have an actual functioning target by loading code into RAM, then maybe probe SDRAM to verify that's functioning, then try loading code into flash again.

It's not trivial to swap flash devices on this board... it's an 8-WSON package.  I don't have reason to question the flash device right now; I've got a number of other things to investigate before I try swapping chips.  You've been quite helpful, thanks.

David R.

5,275 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Thank you for your valuable information!

Best Regards,

Kerry

0 Kudos
5,275 Views
amwilhite
Contributor III

Dave,

Are you using a Quad SPI Flash that is different from the IS25WP064A populated on the EVK?

Can you comment on the changes you made to the flash config structure that differ from those listed in this thread?

Thanks

5,292 Views
dmarks_ls
Senior Contributor I

kerryzhou‌,

I've provided several screenshots above, showing QSPI bus activity, the behavior of the SEGGER programming window, the debugger context when the debug session launches, and the error dialog when I try programming the board directly using MCU Boot Utility.

I'll provide a summary of my configuration and my issues here:

  1. We have a custom RT1052 board with a QSPI flash attached to the secondary pinmux location, as specified above.  The flash was not pre-programmed prior to board assembly; it should be completely blank.
  2. The board has a full complement of DIP switches matching the EVKB, allowing configuration of all relevant BOOT_CFG and BOOT_MODE settings.
  3. We appear to have the correct BOOT_CFG/BOOT_MODE selection (internal boot, QSPI on secondary pinmux) because the RT1052 accesses the QSPI flash after reset.
  4. The MCUXpresso debug launch is not programming the board as it should; the SEGGER window tries comparing flash, gives up at 50%, and then pauses and drops somewhere into the ROM code.
  5. If I configure the RT1052 for "Serial Downloader" instead of "Internal Boot", I can connect the MCU Boot Utility using the USB connection on our board.
  6. The MCU Boot Utility cannot seem to build and/or download a boot image to the RT1052; please see my August 5 reply above.
  7. It is unclear to me whether it should be possible to perform an internal boot / SWD code download to a board with blank flash, or whether is necessary to have some load of code in the flash before a SWD debug launch and code download will work.

Can you provide any assistance for these issues?

5,292 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi David Rodgers,

   Thanks a lot for your detail information.

   In factor, the secondary pin mux option connect to the nor flash, not only related to the BOOT_CFG, BOOT_MODE configuration, you also need to configure the option0 and option1 in the flashloader, that's why you have problems both in the mcuxpresso IDE and MCUBootutility.

   About the MCUXpresso IDE associated with JLINK, it may need to modify some files in the JLINK driver. Actually, if you are using the IAR, it will be more easy to modify it, you can modify the .board files.

But, about the MCUBootUtility tools, I have checked it with the tool author yesterday, but forget to tell you the details, now, please use the MCUbootUtility to download the code again.

1.  RT board enter the serial download mode, BOOT_MODE=01.

2. Open the MCUBootUtility tool, configure the following point:

pastedImage_1.png

option 0[Has option1]=1, option1[enable second pinmux] =1, just choose the secondary pin mux.

Then, when you download the code, the flashloader will try the nor flash which is connect to the secorday mux pins.

Please try it on your side.

Any updated information, please kindly let me know.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
5,292 Views
dmarks_ls
Senior Contributor I

Hi kerryzhou‌, jayheng‌,

Finally coming back around to try and get this working... regarding the MCU Boot Utility, I did modify my Boot Device Configuration to select "Has Option1" and "Enable Second Pinmux", but I'm still getting the error dialog that says

Bootable image is not generated successfully! Make sure you don't put the tool in path with blank space!

See my comment above where I detailed what was occurring.  I've attached a text file (anonymized) of the output of the console window when I hit the "All-in-One Action" button.  You can see from the output that I have the tool installed in a space-free directory path.  Any ideas what's wrong with the Boot Utility?

0 Kudos
5,291 Views
jay_heng
NXP Employee
NXP Employee

For the error "Bootable image is not generated...", Can you please try to use srec/hex file instead of .axf file?

It seems that ROM/Flashloader can access NOR Flash via second pinmux properly,You can connect to NOR device by MCUBootUtility, right?

0 Kudos
5,291 Views
dmarks_ls
Senior Contributor I

Hi jayheng‌,

It appears I've achieved some level of success with the MCU Boot Utility.  I don't have a working target yet, but it appears that the utility is now doing what it's supposed to be doing.  After some investigation, I determined that I needed to make one more setting change for my Cypress S25FL256 device, to select "Set StatusReg2[1]" for Quad Mode:

mcu_boot_utility_device_config.png

I did also add a post-build step to generate an SREC file instead, and that seemed to make the tool much happier.  It passed the phase of generating the bootable file (in the log, the tool says "Origianl image file is a bootable image file"), then spent almost two minutes sending the image to the target.  The utility finished with a stopped clock looking like this:

mcu_boot_utility_maybe_success.png

And now when I do an internal boot, I see a much different pattern on the logic analyzer:

logic_different_boot_pattern.png

This is strongly suggesting to me that I have in fact programmed the flash on my board.  So now I need to turn my attention to getting the debugger to push a useful image into my target hardware.

David R.

0 Kudos
5,291 Views
jay_heng
NXP Employee
NXP Employee

For the reason that you need addtional setting "Set StatusReg2[1]" for Cypress S25FL256, I believe this NOR device is not compatible with JESD216A/B/C.

For the reason that MCUBootUtility spent two minutes flashing image, actually, most of the time is used to readback the image from device, you can disable image readback by setting 'Tools/Image Readback' to 'Manual' in menu bar.

In a word, You can use MCUBootUtility properly now, i believe you can enable FlexSPI NOR boot on secondary pinmux in your board as well.

5,292 Views
dmarples
Contributor IV

I'm not aware of any need to change files in jlink, at least for the

1021...it may of course be different for the other chips. There is a need

to change jlink files when you're moving from hyperflash to qspi (there is

jlink documentation available on this) but not according to which bus

you've got your qpsi device connected to - provided you've not messed with

the fuses then that is set by the configuration pins.

Regards

Dave

5,292 Views
amwilhite
Contributor III

Do you have a reference for the J-Link documentation for changing J-Link files when moving from Hyperflash to QSPI?

5,292 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Austin Wilhite,

  Please check my attached JLinkDevices.xml, it modify the RT105X from hyper flash to QSPI flash.

pastedImage_1.png

Wish it helps you!

Have a great day,
Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

5,291 Views
dmarks_ls
Senior Contributor I

Hi kerryzhou‌,

I can see in the modified XML file that J-Link is being told to use the QSPI driver instead of the HyperFlash driver when selecting an RT1050.  I guess my next question is... why are we forced to hack a J-Link configuration file to make this work?  Shouldn't there be multiple options when selecting the CPU, to choose whether HyperFlash or QSPI flash is in use?  Has anyone from NXP coordinated with SEGGER on this issue?  It shouldn't be necessary to hack the development tools to flash program a device.  Now I have to swap XML files back and forth when switching between my RT1050 EVKB and my RT1050 target hardware board.

I did try to use the above XML file changes to program my board... the behavior is different from the previous configuration, but the board still does not program correctly.  I see the Compare bar grow in small increments to 100%, then the Erase bar grows to 100%, then the SEGGER programming window closes, then a new one opens, the Compare bar quickly grows to 100%, then the Erase bar grows to 100%, then that window closes, and the debugger drops somewhere into the ROM.

David R.

0 Kudos
5,291 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi David Rodgers,

    This is really not very convenient to modify the xml files, it seems when use the JLINK with Fflash or the MCUXpresso IDE need to modify that file.  But if you use the CMSIS DAP debugger or other IDE, you don't modify the install path data, because the official already provide the related files.

   Because your board is the customer board, do you try to download the code to the internal RAM, whether it works OK or not, just make sure your smallest system has no problem at first, you also can try to test the SDK flexspi_nor_polling project, but you need to modify the flexIO pins, test whether you can read/write the external flash memory successfully? Then we can make sure the problem is in the secondary pin mux flash memory side.

    I still don't have the hardware to connect to the secondary pinmux pins, so I don't have the hardware condition to test it directly now.

   Could you use the IAR project, test this SDK code in RAM at first?

SDK_2.6.1_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\flexspi\nor\polling_transfer\iar

  Please modfy the pinmux.c change the flexSPI pins to your own flash related pins.

   If the flash operation works OK, then we can find a simple code, eg, led_blinky, modify the .board(actually configure opt0 and opt1), just use the IAR IDE with JLINK debugger try it again, not use the mcuxpresso IDE at first.

  Any test result please kindly let me know.

Wish it helps you!

Have a great day,
Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
5,291 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Dave Marples,

    You are right, the JLINK file which is needed to mofiy is the JLinkDevices.xml file, as you know, the default setting is used for Hyper Flash.

   The option0 and option1 is used when download the code with MCUBootUtility, it is used to select the secondary pin mux.    

   Could you tell me your RT1020 with JLINK is based on which IDE? MCUXPresso or others, eg IAR, MDK?

 


Have a great day,
Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos