IMX RT1050 crash when data access external memory space

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

IMX RT1050 crash when data access external memory space

2,527 Views
yuzhouhuang
Contributor I

According to RM, memory map of FlexSPI is 0x60000000 -  and SEMC is 0x80000000 - . After configuring SEMC and FlexSPI, I access the data directly.

volatile uint8_t *p = (volatile uint8_t*)0x60000000;

volatile uint8_t *q = (volatile uint8_t*)0x80000000;

printf("%d\n", *p);

printf("%d\n", *q);

Both 3rd and 4th line will take MCU to crash.  But this only happened in A1 version(MIMXRT1052DVL6B), A0 version(MIMXRT1052DVL6A) did not crash and could get correct data.  (I have two version of the board).

Code of my configuration:FlexSPI connect to a Quad SPI NOR Flash, W25Q64JV, SEMC is used connecting an FPGA via SRAM timing configuration.

   IOMUXC_SetPinMux(FLEXSPI_D0_IOMUXC, 1U);
    IOMUXC_SetPinMux(FLEXSPI_D1_IOMUXC, 1U);
    IOMUXC_SetPinMux(FLEXSPI_D2_IOMUXC, 1U);
    IOMUXC_SetPinMux(FLEXSPI_D3_IOMUXC, 1U);
    IOMUXC_SetPinMux(FLEXSPI_CS_IOMUXC, 1U);
    IOMUXC_SetPinMux(FLEXSPI_SCK_IOMUXC, 1U);
    IOMUXC_SetPinConfig(FLEXSPI_D0_IOMUXC, 0x10F1U);
    IOMUXC_SetPinConfig(FLEXSPI_D1_IOMUXC, 0x10F1U);
    IOMUXC_SetPinConfig(FLEXSPI_D2_IOMUXC, 0x10F1U);
    IOMUXC_SetPinConfig(FLEXSPI_D3_IOMUXC, 0x10F1U);
    IOMUXC_SetPinConfig(FLEXSPI_CS_IOMUXC, 0x10F1U);
    IOMUXC_SetPinConfig(FLEXSPI_SCK_IOMUXC, 0x10F1U);

    flexspi_config_t config;
    FLEXSPI_GetDefaultConfig(&config);
    config.ahbConfig.enableAHBPrefetch = true;
    config.ahbConfig.enableAHBCachable = true;
    // config.ahbConfig.enableAHBBufferable = true;
    // config.ahbConfig.enableAHBWriteIpTxFifo = true;
    // config.ahbConfig.enableAHBWriteIpRxFifo = true;
    // config.ahbConfig.enableClearAHBBufferOpt = true;
    config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromSckPad;
    FLEXSPI_Init(APP_FLEXSPI, &config);
    flexspi_device_config_t device_config = 
    {
        .flexspiRootClk = (uint32_t)clock_manager.FlexSPIFrequency,
        .isSck2Enabled = false,
        .flashSize = APP_FLASH_SIZE_KB,
        .CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
        .CSInterval = 2,
        .CSHoldTime = 2,
        .CSSetupTime = 2,
        .dataValidTime = 0,
        .columnspace = 0,
        .enableWordAddress = 0,
        .AWRSeqIndex = 0,
        .AWRSeqNumber = 0,
        .ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD, // FIXME:
        .ARDSeqNumber = 1,
        .AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
        .AHBWriteWaitInterval = 0,
        .enableWriteMask = false,
    };
    FLEXSPI_SetFlashConfig(APP_FLEXSPI, &device_config, kFLEXSPI_PortA1);
    FLEXSPI_UpdateLUT(APP_FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH);

    IOMUXC_SetPinMux(SEMC_DA0_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA1_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA2_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA3_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA4_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA5_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA6_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA7_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA8_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA9_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA10_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA11_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA12_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA13_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA14_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_DA15_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_WE_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_OE_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_CS1_IOMUXC, 0U);
    IOMUXC_SetPinMux(SEMC_ADV_IOMUXC, 0U);
    //IOMUXC_SetPinConfig(SEMC_DA0_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA1_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA2_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA3_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA4_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA5_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA6_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA7_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA8_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA9_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA10_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA11_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA12_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA13_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA14_IOMUXC, 0x10B0U);
    //IOMUXC_SetPinConfig(SEMC_DA15_IOMUXC, 0x10B0U);
    IOMUXC_SetPinConfig(SEMC_WE_IOMUXC, 0xD0F1U);
    IOMUXC_SetPinConfig(SEMC_OE_IOMUXC, 0xD0F1U);
    IOMUXC_SetPinConfig(SEMC_CS1_IOMUXC, 0xD0F1U);
    // IOMUXC_SetPinConfig(SEMC_ADV_IOMUXC, 0xD0F1U);
    IOMUXC_SetPinMux(FPGA_RST_IOMUXC, 0U);
    IOMUXC_SetPinConfig(FPGA_RST_IOMUXC, 0x10B0U);
    // 
    gpio_pin_config_t gpio_config;
    gpio_config.direction = kGPIO_DigitalOutput;
    gpio_config.interruptMode = kGPIO_NoIntmode;
    gpio_config.outputLogic = 0;
    GPIO_PinInit(FPGA_RST_GPIO, FPGA_RST_PIN, &gpio_config);

    // initialize SEMC
    semc_config_t semc_config;
    SEMC_GetDefaultConfig(&semc_config);
    SEMC_Init(APP_SEMC, &semc_config);

    semc_sram_config_t sram_config;
    sram_config.cePinMux = kSEMC_MUXA8;                           /*!< The CE# pin mux setting. */
    sram_config.addr27 = kSEMC_MORA27_NONE;                             /*!< The Addr bit 27 pin mux setting. */
    sram_config.address = 0x80000000;                            /*!< The base address. */
    sram_config.memsize_kbytes = 64;               /*!< The memory size in unit of kbytes. */
    sram_config.addrPortWidth = 16;                 /*!< The address port width. */
    sram_config.advActivePolarity = kSEMC_AdvActiveLow; /*!< ADV# polarity 1: active high, 0: active low. */
    sram_config.addrMode = kSEMC_AddrDataMux;             /*!< Address mode. */
    sram_config.burstLen = kSEMC_Nor_BurstLen1;             /*!< Burst length. */
    sram_config.portSize = kSEMC_PortSize16Bit;             /*!< Port size. */
    sram_config.tCeSetup_Ns = 2;                   /*!< The CE setup time. */
    sram_config.tCeHold_Ns = 2;                    /*!< The CE hold time. */
    sram_config.tCeInterval_Ns = 30;                /*!< CE interval minimum time. */
    sram_config.tAddrSetup_Ns = 25;                 /*!< The address setup time. */
    sram_config.tAddrHold_Ns = 0;                  /*!< The address hold time. */
    sram_config.tWeLow_Ns = 25;                         /*!< WE low time for async mode. */
    sram_config.tWeHigh_Ns = 0;                         /*!< WE high time for async mode. */
    sram_config.tReLow_Ns = 25;                         /*!< RE low time for async mode. */
    sram_config.tReHigh_Ns = 0;                         /*!< RE high time for async mode. */
    sram_config.tTurnAround_Ns = 2;                     /*!< Turnaround time for async mode. */
    sram_config.tAddr2WriteHold_Ns = 0;                 /*!< Address to write data hold time for async mode. */
    sram_config.tWriteSetup_Ns = 0;
    sram_config.tWriteHold_Ns = 0;
    sram_config.latencyCount = 0;
    sram_config.readCycle = 0;
    SEMC_ConfigureSRAM(APP_SEMC, &sram_config, clock_manager.SEMCFrequency);
    APP_SEMC->SRAMCR1 = SEMC_SRAMCR1_CES(0) |             // CE setup 1-16 cycles
                        SEMC_SRAMCR1_CEH(1) |             // CE hold 1-16 cycles
                        SEMC_SRAMCR1_AS(5) |              // address setup 1-16 cycles 
                        SEMC_SRAMCR1_AH(1) |              // address hold 1-16 cycles
                        SEMC_SRAMCR1_WEL(5) |             // WE low 1-16 cycles
                        SEMC_SRAMCR1_WEH(0) |             // WE high 1-16 cycles
                        SEMC_SRAMCR1_REL(5) |             // RE low 1-16 cycles
                        SEMC_SRAMCR1_REH(0);              // RE high 1-16 cycles
    APP_SEMC->SRAMCR2 = SEMC_SRAMCR2_WDS(0) |             // Write data setup 1-16 cycles
                        SEMC_SRAMCR2_WDH(0) |             // Write data hold 1-16 cycles
                        SEMC_SRAMCR2_TA(1) |              // Turnaround 1-16 cycles
                        SEMC_SRAMCR2_AWDH(3) |            // addr to write data hold time 1-16 cycles
                        SEMC_SRAMCR2_CEITV(3);            // CE interval time 1-16 cycles
Labels (1)
0 Kudos
Reply
3 Replies

1,837 Views
igorpadykov
NXP Employee
NXP Employee

Hi Yuzhou

one can check AN12146 Migrating from silicon Rev A0 to Rev A1 

which suggests specific for A1 software changes

https://www.nxp.com/docs/en/nxp/application-notes/AN12146.pdf 

Also one can try to debug it using jtag debugger.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

1,837 Views
yuzhouhuang
Contributor I

Thanks, igorpadykov.

The cause is described in AN12146 page 3.

SEMC CCM: add bit filed to control semc_exsc clock, must be enabled always

FLEXSPI CCM: add bit filed to control flexspi_exsc clock, must be enabled always

The old SDK(version 2.3.0) initialize register CCM CCGR0 and CCM CCGR1 by

CCM->CCGR0 = 0x00C0000FU;
CCM->CCGR1 = 0x30000000U;

This is not correct in revision A1. The correct value should be

CCM->CCGR0 = 0x00C000CFU;  
CCM->CCGR1 = 0x300C0000U;  
0 Kudos
Reply

1,837 Views
christiangradl
Contributor III

Hi,
i tried your example and its running.

Now, i do some tests with different burstlength (1-64), put an oscilloscope on the CS and use the assembler

instructions

   VLDM    r1, {s16-s17}

   VSTM    r0, {s16-s17}

Burst does not work here! There are 4 CS raising when calling VLDM? I excpected 2 CS raising.

A change to burstlen has no effect.

Please can you tell me, what i should do to enable burst access on SRAM?

My FPGA do an autoincrement of the address, so after the first access it do not need any further address info-

Christian

0 Kudos
Reply