Debugging Hard Fault in Application with iMX RT1064 and QSPI Memory, XIP execution

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

Debugging Hard Fault in Application with iMX RT1064 and QSPI Memory, XIP execution

Jump to solution
245 Views
mnagoga
Contributor I

 

Hardware Configuration:

  • Board: iMX RT1064 uCOM board (revision PB1) mounted on a uCOM Carrier board (Embedded Artists)
  • Memory: IS25LP064A 8 MB QSPI memory on the carrier board connected to FlexSpi interface (base 0x60000000) 

Issue Description: I have successfully implemented a simple bootloader on the QSPI internal memory, which initializes the SDRAM (32 MB), FlexSpi interface, and then jumps to the application stored in the external QSPI memory for XIP execution. This setup works correctly with a basic "hello world" application (blinking LED and console output).

However, when I attempt to run a more complex application containing extensive C++ code and utilizing the graphic controller, the system quickly encounters a hard fault from a seemingly random address. The same application works perfectly in the internal QSPI memory.

Code Used for Initialization (based on the example polling_transfer from the sdk boards/evkmimxrt1064/driver_examples/flexspi/nor/polling_transfer):

 

 

 

static void init_qspi_flash_on_front_panel(void)
{
    SETUP(IOMUXC_GPIO_AD_B1_09_FLEXSPIA_DQS, 1, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
    SETUP(IOMUXC_GPIO_AD_B1_10_FLEXSPIA_DATA03, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
    SETUP(IOMUXC_GPIO_AD_B1_11_FLEXSPIA_DATA02, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
    SETUP(IOMUXC_GPIO_AD_B1_12_FLEXSPIA_DATA01, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
    SETUP(IOMUXC_GPIO_AD_B1_13_FLEXSPIA_DATA00, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
    SETUP(IOMUXC_GPIO_AD_B1_14_FLEXSPIA_SCLK,   0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
    SETUP(IOMUXC_GPIO_AD_B1_15_FLEXSPIA_SS0_B,  0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
}

 

 

 

 

void init_ext_flex_spi()
{
    uint32_t i = 0;
    status_t status;
    uint8_t vendorID = 0;
    flexspi_nor_flash_init(EXAMPLE_FLEXSPI);

    /* Get vendor ID. */
    status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
    if (status != kStatus_Success)
    {
        LOG("FAIL flexspi_nor_get_vendor_id");
        Q_ASSERT(false);
    }
    LOG("Vendor ID: 0x%x\r\n", vendorID);

    /* Enter quad mode. */
    status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
    if (status != kStatus_Success)
    {
        LOG("FAIL flexspi_nor_enable_quad_mode");
        Q_ASSERT(false);
    }
}

 

 

 

 

void flexspi_nor_flash_init(FLEXSPI_Type *base)
{
    flexspi_config_t config;

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
    flexspi_cache_status_t cacheStatus;
    flexspi_nor_disable_cache(&cacheStatus);
#endif

    flexspi_clock_init();

    /*Get FLEXSPI default settings and configure the flexspi. */
    FLEXSPI_GetDefaultConfig(&config);

    /*Set AHB buffer size for reading data through AHB bus. */
    config.ahbConfig.enableAHBPrefetch    = true;
    config.ahbConfig.enableAHBBufferable  = true;
    config.ahbConfig.enableReadAddressOpt = true;
    config.ahbConfig.enableAHBCachable    = true;
    config.rxSampleClock                  = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
    FLEXSPI_Init(base, &config);

    /* Configure flash settings according to serial flash feature. */
    FLEXSPI_SetFlashConfig(base, &deviceconfig, FLASH_PORT);

    /* Update LUT table. */
    FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH);

    /* Do software reset. */
    FLEXSPI_SoftwareReset(base);

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
    flexspi_nor_enable_cache(cacheStatus);
#endif
}

 

 

 

 

flexspi_device_config_t deviceconfig = {
        .flexspiRootClk       = 120000000,
        .flashSize            = FLASH_SIZE,
        .CSIntervalUnit       = kFLEXSPI_CsIntervalUnit1SckCycle,
        .CSInterval           = 2,
        .CSHoldTime           = 3,
        .CSSetupTime          = 3,
        .dataValidTime        = 0,
        .columnspace          = 0,
        .enableWordAddress    = 0,
        .AWRSeqIndex          = 0,
        .AWRSeqNumber         = 0,
        .ARDSeqIndex          = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,
        .ARDSeqNumber         = 1,
        .AHBWriteWaitUnit     = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
        .AHBWriteWaitInterval = 0,
};

 

 

 

 

void flexspi_clock_init()
{
    const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
    CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);
    CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
    CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2);   /* flexspi clock 120M. */
}

 

 

 

The FlexSpi clock is set to 120 MHz. I attempted to increase it to 132 MHz (by using PLL2_PFD2 set to 396 MHz and FlexSpi divider set to 3), but this resulted in incorrect vendor ID readings.

Request for Assistance:

  1. Debugging Approach: What is the recommended way to debug the hard fault issue occurring in my application on the external QSPI memory? Are there specific tools, techniques, or steps that can help pinpoint the source of the fault effectively?
  2. Potential Hardware Issue: Could this be a hardware problem, such as an issue with the signal integrity? Notably, the vendor ID is read correctly at 120 MHz but incorrectly at 132 MHz. How is this discrepancy possible, and what implications might it have on the overall stability?
  3.  Custom Board Behavior: We have a custom-designed board based on the iMX RT1064 uCOM module. The application running from the external memory works longer on this custom board compared to the uCOM Carrier board but still eventually encounters a hard fault after a few seconds of operation. What factors should be considered in this context, and could there be specific hardware or configuration issues at play?

Thank you for your assistance.

Michael

Labels (1)
Tags (2)
0 Kudos
Reply
1 Solution
132 Views
mnagoga
Contributor I
The problem has been solved for our custom carrier board. There was a hardware issue with the FlexSPI DQS pin (IOMUXC_GPIO_AD_B1_09_FLEXSPIA_DQS), which I use for the QSPI quad mode. It was connected to a circuit indicating whether the peripherals are powered on. After disconnecting the lane, I was able to use the memory at 120 MHz quad mode without any problems.
 
However, on the embedded artistst carrier board, I was never able to get quad mode working, even at very low frequencies.

View solution in original post

0 Kudos
Reply
1 Reply
133 Views
mnagoga
Contributor I
The problem has been solved for our custom carrier board. There was a hardware issue with the FlexSPI DQS pin (IOMUXC_GPIO_AD_B1_09_FLEXSPIA_DQS), which I use for the QSPI quad mode. It was connected to a circuit indicating whether the peripherals are powered on. After disconnecting the lane, I was able to use the memory at 120 MHz quad mode without any problems.
 
However, on the embedded artistst carrier board, I was never able to get quad mode working, even at very low frequencies.
0 Kudos
Reply