AnsweredAssumed Answered

Converted project evkmimxrt1064_flash_component_nor.  How can I reset FLEXCAN in a way that I don't require power cycle prior to running?

Question asked by Paul Roberts on Mar 6, 2020
Latest reply on Mar 15, 2020 by Kerry Zhou

MCUXpresso 10.3 MIMXRT1064 Eval Board.  SDK 2.6.1.

I converted project evkmimxrt1064_flash_component_nor.  Here, I describe how I did that.  My actual questions show up in items 5 and 6 below.

 

1) The example project evkmimxrt1064_flash_component_nor is only available in version 2.7 of the SDK, which only works with MCUXpresso 11.1.  We can't use 11.1, because they stopped supporting the config tool in 11.1.  It's there, but somehow I don't have access to it.  (I forget the error message, as it's been a long time now.  It appears we're stuck in 10.3 for the forseeable future until this other problematic issues that exist in 11.1 are addressed, but alas, 'tis a subject for another day!)

 

2) I brought the files form the project into a copy of the "hello world" example, and deleted the hello_world.c file.  As needed, I just dropped files from 11.1 project evkmimxrt1064_flash_component_nor into the source folder of my new 10.3 project, including the 3 files from the "nor_flash" folder of the original project.

 

3) At the top of nor_flash.c, I made the following modification:

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define useEvalBoardChipFlash 0
#define useDoEraseVerifytest 0

#if useEvalBoardChipFlash
#define EXAMPLE_FLEXSPI FLEXSPI
#define FLASH_SIZE 0x2000 /* 64Mb/KByte */
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
#define FLASH_PAGE_SIZE 256
#define NOR_FLASH_START_ADDRESS 0U
#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_FlexSpi
#else
#define EXAMPLE_FLEXSPI FLEXSPI2
#define FLASH_SIZE 0x1000 /* 32Mb/KByte */
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI2_AMBA_BASE
#define FLASH_PAGE_SIZE 256
#define NOR_FLASH_START_ADDRESS 0U
#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_FlexSpi2
#endif
4) I modified main() as follows.  (See below.) Note that
    a) Without calling CLOCK_SetMux(kCLOCK_UartMux, prior to calling BOARD_InitDebugConsole(), my debug port was not working when I select "Link application to RAM" in Tool Settings=>MCU Linker=>Managed Linker Script.
   b) I converted the example to one that uses the internal flash at address 0x70000000.  It runs with useEvalBoardChipFlash=0 and useDoEraseVerifytest=0, as long as I do a power cycle prior to running the program.  I verify that my erasures and writes actually work using the Segger JFlash utility.  I can see the byte pattern in the JFlash record starting at address 0x70040000.
5) Since I did "Link application to RAM,"  no flash copy of my program is evidently retained, as nothing is output on power cycle without the debugger.  It appears I'm going to have create my own "unmanaged" linker script (which I've done in the past with other microcontrollers, including Kinetis K22).  It would be nice to not have to go the unmanaged route.  Does anyone out there know how I might approach doing this?  I ask because it just seems that managed scripts are a bit easier to work with.
6) If I try to debug using flash (unchecking the "Link application to RAM" box), it appears that the call to FLEXSPI_Init() commits hari-kari when it tries to call FLEXSPI_SoftwareReset().  It seems as though you may have to be executing out of RAM when you call that?  If someone knows exactly why this may be, I'm all ears.
int main(void)
{
    status_t status;
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    CLOCK_SetMux(kCLOCK_UartMux, 1); // use 24mHz clock
    BOARD_InitDebugConsole();
    PRINTF("\r\nNor Flash test begin.");
    const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
#if useEvalBoardChipFlash
    CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);   /* Set PLL3 PFD0 clock 360MHZ. */
    CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
    CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2);   /* flexspi clock 120M. */
#else
    CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
    CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);   /* Set PLL3 PFD0 clock 360MHZ. */
    CLOCK_SetMux(kCLOCK_Flexspi2Mux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
    CLOCK_SetDiv(kCLOCK_Flexspi2Div, 2);   /* flexspi clock 120M. */
#endif
    PRINTF("\r\nFlexSPI clock is running.");
    /* Initialize FLEXSPI */
    flexspi_config_t config;
    /* 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_Deinit(EXAMPLE_FLEXSPI);  //! I tried doing this in hopes that it would non-first-time runs
             //! to not hang in Nor_Flash_Init().  No effect.
             //! Power cycle is required on each run!!
             //! 20200304 PJR
    FLEXSPI_Init(EXAMPLE_FLEXSPI, &config);
    PRINTF("\r\n***NOR Flash Component Demo Start!***\r\n");
    PRINTF("\r\n***NOR Flash Initialization Start!***\r\n");
    status = Nor_Flash_Init(&norConfig, &norHandle);
    if (status != kStatus_Success)
    {
        PRINTF("\r\n***NOR Flash Initialization Failed!***\r\n");
        ErrorTrap();
    }
    PRINTF("\r\n***NOR Flash Initialization Success!***\r\n");
#if useEvalBoardChipFlash
    /* Erase chip */
    PRINTF("\r\n***NOR Flash Erase Chip Start!***\r\n");
    status = Nor_Flash_Erase_Chip(&norHandle);
    if (status != kStatus_Success)
    {
        PRINTF("\r\n***NOR Flash Erase Chip Failed!***\r\n");
        ErrorTrap();
    }
#endif
#if useEvalBoardChipFlash
    const uint32_t pageOffset = 256;
#else
    const uint32_t pageOffset = 1024;
#endif
    for (uint32_t pageIndex = pageOffset; pageIndex < (pageOffset + norHandle.bytesInPageSize); pageIndex++)
    {
        uint32_t address = NOR_FLASH_START_ADDRESS + norHandle.bytesInPageSize * pageIndex;
#if useEvalBoardChipFlash
        status = Nor_Flash_Read(&norHandle, address, mem_readBuffer, norHandle.bytesInPageSize);
        if (status != kStatus_Success)
        {
            PRINTF("\r\n***NOR Flash Read Page Failed!***\r\n");
            ErrorTrap();
        }
        for (uint32_t bytesIndex = 0; bytesIndex < norHandle.bytesInPageSize; bytesIndex++)
        {
            if (mem_readBuffer[bytesIndex] != 0xFF)
            {
                PRINTF("\r\n***NOR Flash Erase Chip Failed!***\r\n");
                ErrorTrap();
            }
        }
#endif
        /* Program the page data. */
        /* Initialize the write buffers. */
        for (uint32_t i = 0; i < norHandle.bytesInPageSize; i++)
        {
            mem_writeBuffer[i] = i;
        }
        PRINTF("\r\n");
        status = Nor_Flash_Page_Program(&norHandle, address, mem_writeBuffer);
        if (status != kStatus_Success)
        {
            PRINTF("\r\n***NOR Flash Page %d Program Failed!***\r\n", pageIndex);
            ErrorTrap();
        }
        /* Read page data and check if the data read is equal to the data programed. */
        status = Nor_Flash_Read(&norHandle, address, mem_readBuffer, norHandle.bytesInPageSize);
        if (status != kStatus_Success)
        {
            PRINTF("\r\n***NOR Flash Page %d Read Failed!***\r\n", pageIndex);
            ErrorTrap();
        }
        if (memcmp(mem_writeBuffer, mem_readBuffer, norHandle.bytesInPageSize) != 0)
        {
            PRINTF("\r\n***NOR Flash Page %d Read/Write Failed!***\r\n", pageIndex);
            ErrorTrap();
        }
        PRINTF("\r\n***NOR Flash Page %d Read/Write Success!***\r\n", pageIndex);
#if useDoEraseVerifytest
        /* Erase Block */
        status = Nor_Flash_Erase_Block(&norHandle, address, norHandle.bytesInPageSize);
        if (status != kStatus_Success)
        {
            PRINTF("\r\n***NOR Flash Erase Block Failed!***\r\n");
            ErrorTrap();
        }
        status = Nor_Flash_Read(&norHandle, address, mem_readBuffer, norHandle.bytesInPageSize);
        if (status != kStatus_Success)
        {
            PRINTF("\r\n***NOR Flash Page Read Failed!***\r\n");
            ErrorTrap();
        }
        for (uint32_t bytesIndex = 0; bytesIndex < norHandle.bytesInPageSize; bytesIndex++)
        {
            if (mem_readBuffer[bytesIndex] != 0xFF)
            {
                PRINTF("\r\n***NOR Flash Erase Block Failed!***\r\n");
                ErrorTrap();
            }
        }
#endif // useDoEraseVerifytest
    }
    PRINTF("\r\n***NOR Flash All Pages Read/Write Success!***\r\n");
    while (1)
    {
    }
}

Outcomes