Issues with i.MXRT1062 and IS25WX256 Octal flash

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

Issues with i.MXRT1062 and IS25WX256 Octal flash

Jump to solution
1,185 Views
robvos
Contributor II

Good day,

We are developing a product that uses the MIMXRT1062DVL6B together with IS25WX256-JHLE flash. It is a custom board, but we have verified that booting from flash is working with a basic LED blinking firmware, flashed via USB with NXP MCU BootUtility v6.2.0.

We set the Device Model to "ISSI_OctalSPI_IS25LXxxx_IS25WXxxx", and only change the frequency 30 MHz.

Now that we continued development we encountered two separate problems:

1: The ROM bootloader refuses to boot an image larger than 128KiB

Firmware smaller than 128K boots without a problem, but anything larger and the firmware does not boot (attaching debugger shows only code from ROM area is running).

We rule out other issues by making a simple change:

We patch the "length" field in boot_data to a number below 128K:

 

boot_data at 0x60001020
uint32_t start
uint32_t length <-- Only patched this from 200K to 30K!
uint32_t plugin

 

Then, the firmware boots up without issue, even though it actually is larger! Areas above 128K in the flash are accessible by the firmware without a problem.

So now we can boot larger images, but it feels like a bad hack. What's the problem?

2: Flashing via J-Link does not work

Being able to use J-Link and Ozone debugger for flashing would greatly help with development.

How do we get this working smoothly?

We have tried the builtin-in flashloader from SEGGER as well as RT-UFL.
I have described the issue here in more detail: https://github.com/JayHeng/RT-UFL/issues/16

 

 

Labels (1)
0 Kudos
Reply
1 Solution
939 Views
robvos
Contributor II

Alright, I have written a minimal flashloader from scratch which seems to be working.

Important points for other people finding this thread:

  • Flash chip should be reset via its RESET# pin before using the ROM API! RT-UFL does not do this.
  • The ROM API (fsl_romapi.h) works great! Take the option0 value from NXP MCU Boot Utility and it worked straight away, erase/program/shows up at 0x60000000, etc.
  • When testing the flashloader I would sometimes get "PC of target system has unexpected value after preparing target (PC = 0x00000000)!", not sure why. I started using ufl_init_hardware_imxrt106x() from RT-UFL (instead of BOARD_InitBootClocks(), etc.) and it solved the problem. May be a code size issue or related to my toolchain (zig toolchain/clang/lld).
  • Follow the instructions on wiki.segger.com/SEGGER_Flash_Loader on how to set up the sections in the linker etc. Note that this uses different functions from RT-UFL (CMSIS loader API) but otherwise functions identically. The SEGGER API is significantly faster because it will program/erase multiple sectors in a single function call. They mention some .a binary but it worked without it for me.
  • Developing your own flashloader is annoying, but at least you can tailor it to make the flashloader blink the LED on your board, or even output stuff on UART to help debug it.
  • For my firmware image, I copied the 8KiB boot header (FCFB...) generated by NXP MCU Boot Uility and put it in front of the .text section via the linker. So I can flash empty boards with the J-Link using only the .elf file.
  • Also reset the flash chip in SEGGER_FL_Restore(), so that the ROM bootloader starts up properly (can also do this in JLinkScript).

 

Basic code to get started on the flashloader:

 

    serial_nor_config_option_t option;
    option.option0.U = 0xC0603001;
    option.option1.U = 0;
    
    // NOTE(robin): Reset the flash chip as it may be in an invalid state.
    BOARD_INITPINS_FLASH_RST_GPIO->DR_CLEAR = BOARD_INITPINS_FLASH_RST_PIN_MASK;
    for(volatile int i = 0; i < 1000; ++i) {}
    BOARD_INITPINS_FLASH_RST_GPIO->DR_SET = BOARD_INITPINS_FLASH_RST_PIN_MASK;
    for(volatile int i = 0; i < 1000; ++i) {}

    status_t volatile status = ROM_FLEXSPI_NorFlash_GetConfig(0, &flashConfig, &option);
    if(status == kStatus_Success)
    {
        status = ROM_FLEXSPI_NorFlash_Init(0, &flashConfig);
        if(status == kStatus_Success)
        {
            // Go nuts
        }
    }  

 

 

 

View solution in original post

0 Kudos
Reply
7 Replies
940 Views
robvos
Contributor II

Alright, I have written a minimal flashloader from scratch which seems to be working.

Important points for other people finding this thread:

  • Flash chip should be reset via its RESET# pin before using the ROM API! RT-UFL does not do this.
  • The ROM API (fsl_romapi.h) works great! Take the option0 value from NXP MCU Boot Utility and it worked straight away, erase/program/shows up at 0x60000000, etc.
  • When testing the flashloader I would sometimes get "PC of target system has unexpected value after preparing target (PC = 0x00000000)!", not sure why. I started using ufl_init_hardware_imxrt106x() from RT-UFL (instead of BOARD_InitBootClocks(), etc.) and it solved the problem. May be a code size issue or related to my toolchain (zig toolchain/clang/lld).
  • Follow the instructions on wiki.segger.com/SEGGER_Flash_Loader on how to set up the sections in the linker etc. Note that this uses different functions from RT-UFL (CMSIS loader API) but otherwise functions identically. The SEGGER API is significantly faster because it will program/erase multiple sectors in a single function call. They mention some .a binary but it worked without it for me.
  • Developing your own flashloader is annoying, but at least you can tailor it to make the flashloader blink the LED on your board, or even output stuff on UART to help debug it.
  • For my firmware image, I copied the 8KiB boot header (FCFB...) generated by NXP MCU Boot Uility and put it in front of the .text section via the linker. So I can flash empty boards with the J-Link using only the .elf file.
  • Also reset the flash chip in SEGGER_FL_Restore(), so that the ROM bootloader starts up properly (can also do this in JLinkScript).

 

Basic code to get started on the flashloader:

 

    serial_nor_config_option_t option;
    option.option0.U = 0xC0603001;
    option.option1.U = 0;
    
    // NOTE(robin): Reset the flash chip as it may be in an invalid state.
    BOARD_INITPINS_FLASH_RST_GPIO->DR_CLEAR = BOARD_INITPINS_FLASH_RST_PIN_MASK;
    for(volatile int i = 0; i < 1000; ++i) {}
    BOARD_INITPINS_FLASH_RST_GPIO->DR_SET = BOARD_INITPINS_FLASH_RST_PIN_MASK;
    for(volatile int i = 0; i < 1000; ++i) {}

    status_t volatile status = ROM_FLEXSPI_NorFlash_GetConfig(0, &flashConfig, &option);
    if(status == kStatus_Success)
    {
        status = ROM_FLEXSPI_NorFlash_Init(0, &flashConfig);
        if(status == kStatus_Success)
        {
            // Go nuts
        }
    }  

 

 

 

0 Kudos
Reply
1,083 Views
Sam_Gao
NXP Employee
NXP Employee

Hi @robvos 

Q1. It's strange for this case, it should be workable based on the hardware. Would you please try use MCUXpresso to double check if it is work? 

BTW, "We set the Device Model to "ISSI_OctalSPI_IS25LXxxx_IS25WXxxx", and only change the frequency 30 MHz." How to change and what's the meaning?

 

B.R

Sam

0 Kudos
Reply
1,077 Views
robvos
Contributor II

BTW, "We set the Device Model to "ISSI_OctalSPI_IS25LXxxx_IS25WXxxx", and only change the frequency 30 MHz." How to change and what's the meaning?

This is what I configure in the NXP MCU Boot Utility.

 

Would you please try use MCUXpresso to double check if it is work? 

Flashing via MCUXpresso does not work. Using the "GUI Flash Tool" button results in an error:

robvos_0-1719571067818.png

 

0 Kudos
Reply
1,022 Views
Sam_Gao
NXP Employee
NXP Employee

Hi @robvos 

I double checked with NXP MCUXpresso (default is CMSIS-DAP), it doesn't directly support Octal flashloader (MCUXpressoIDE_11.9.1_2170\ide\LinkServer\Examples\Flashdrivers\NXP\iMXRT). 

Plz try with the attchement (for RT1170) from link https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/RT1170-Octal-flash-enablement/ta-p/1498369  and https://github.com/JayHeng/RT-UFL/blob/master/README-en.md for reference. 

I checked with the author of MCUBootUtility and RT-UFL about the two questions, it should work well without any 128KB limitation.

 

B.R

Sam

 

0 Kudos
Reply
1,010 Views
robvos
Contributor II

Thank you for the link.

So to be clear, this is what I should have?

 

  <Device>
    <ChipInfo      Vendor="NXP"
                   Name="MIMXRT1062_UFL_octalFlash"
                   WorkRAMAddr="0x20200000"
                   WorkRAMSize="0x00040000"
                   Core="JLINK_CORE_CORTEX_M7"
                   Aliases="MIMXRT1062_Octal" />
    <FlashBankInfo Name="Octal Flash"
                   BaseAddr="0x60000000"
                   MaxSize="0x02000000"
                   Loader="Devices/NXP/iMXRT_UFL/MIMXRT_FLEXSPI_UV5_UFL.FLM"
                   LoaderType="FLASH_ALGO_TYPE_OPEN" />
  </Device>

 

 In the J-Link pop-up, the Compare fills to 100% but then fails to erase:

 

Device "MIMXRT1062_OCTAL" selected.
Found SW-DP with ID 0x0BD11477
DPIDR: 0x0BD11477
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[1]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x04770041)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FD000
CPUID register: 0x411FC271. Implementer code: 0x41 (ARM)
Cache: L1 I/D-cache present
Found Cortex-M7 r1p1, Little endian.
FPUnit: 8 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] @ E00FD000
[0][0]: E00FE000 CID B105100D PID 000BB4C8 ROM Table
ROMTbl[1] @ E00FE000
[1][0]: E00FF000 CID B105100D PID 000BB4C7 ROM Table
ROMTbl[2] @ E00FF000
[2][0]: E000E000 CID B105E00D PID 000BB00C SCS-M7
[2][1]: E0001000 CID B105E00D PID 000BB002 DWT
[2][2]: E0002000 CID B105E00D PID 000BB00E FPB-M7
[2][3]: E0000000 CID B105E00D PID 000BB001 ITM
[1][1]: E0041000 CID B105900D PID 001BB975 ETM-M7
[1][2]: E0042000 CID B105900D PID 004BB906 CTI
[0][1]: E0040000 CID B105900D PID 000BB9A9 TPIU-M7
[0][2]: E0043000 CID B105F00D PID 001BB101 TSG
I-Cache L1: 32 KB, 512 Sets, 32 Bytes/Line, 2-Way
D-Cache L1: 32 KB, 256 Sets, 32 Bytes/Line, 4-Way
Connected to target device.
J-Link/J-Trace serial number: 601014830
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Failed to erase sectors.

 

I also tried with MIMXRT1060_UFL_L0, which gave the same result.

I get the feeling I will need to build RT-UFL myself to debug this properly. Sadly, its build system seems to depend on either Keil MDK or IAR, which are paid solutions we do not use. So I will need to convert it first..

0 Kudos
Reply
1,138 Views
Masmiseim
Senior Contributor I

Hallo @robvos 

 

We have a design with IS25WX064 which is working okay.

Regarding 2):

The Segger Flash loader does not support Octa-SPI Flash-Memory. Some IDEs use own flash-loaders which may support octa-spi (also via Segger J-Link). We also used an adapted flash-loader.

Regards

0 Kudos
Reply
1,110 Views
robvos
Contributor II

Hi Masmiseim,

Which flash loader are you using?

0 Kudos
Reply