RA6M5 LevelX on QSPI and MCUBoot

Hello,

I've been working on a test project on the EK-RA6M5 board which included several various FSP modules/stacks for testing and includes a working NetX FTP server based on the QSPI flash. After successfully getting all those to work in a separate project Ive had gone ahead and started a new "official" project that only has the NetX FTP on QSPI flash stacks in it. I'm trying to use the MCUBoot stack as well and have created a boot loader project that successfully launches this new FTP server project. However, since using the new project whenever the program calls lx_nor_flash_open() it throws a BSP_CFG_HANDLE_UNRECOVERABLE_ERROR when trying to call the rm_filex_levelx_nor_spi_callback() for the first write operation. I've tried looking into several fixes and none of them seem to have worked. I've tried:

  • Increasing both the main heap and main stack size in the boot loader project
  • Increasing both the main heap and main stack size in the FTP server project
  • Increasing the thread stack size for the FTP server thread.
  • Adding Parameter Checking beyond just BSP for several stacks.
  • Messing around with QSPI settings.
  • Erasing the whole QSPI chip.
  • Various other small things.

I tried looking into the MSP and PSP as well but they seem to set appropriately by the RA MCUBoot port. The MSP and PSP are both higher than the MSPLIM and PSPLIM respectively. I could be missing something here but I am no expert when it comes to boot loaders or ARM architecture.

Here is a photo of the trace.

I also have the a callback for the FileX I/O stack here:

And here's the code that's running in the only thread that is running:

I've tried using the format code that's supplied in the g_levelx_nor_quick_setup() code and tried using R_QSPI_Erase(p_ctrl, (uint8_t *)QSPI_DEVICE_START_ADDRESS, SPI_FLASH_ERASE_SIZE_CHIP_ERASE) which is the only relevant line of code in the currently not called qspi_format_device function.

I'm not sure what to even check anymore, any insight would be appreciated.

  • I should add that I am trying to use the QSPI flash as both the secondary image staging area for the MCUBoot stack and the other portion of QSPI flash as the storage media for the FTP server.

    Here are the MCUBoot settings for the bootloader project:

    And here are the LevelX Nor port settings in the FTP server project:

  • I don't know the MCUBoot related issues, but I'm facing the same QSPI problem from time to time with some brand new boards and after some failed QSPI operation. There must be an elegant way to solve it, but for the moment my approach is to flash a "repairing" firmware that basically erases and formats the QSPI AFTER the QSPI and the FileX have been initialized. Here is my code:

    NOTE: The DBG_PRINT() and DBG_PRINT_ERR() are just RTT calls


    system init:
    {
    ...

    //
    // Initialize QSPI:
    //
    err = CQspi_Ini(); // Your board QSPI initialization as in the Renesas examples
    if (err != FSP_SUCCESS)
    { DBG_PRINT_ERR("Error initializing QSPI Flash device\r\n");
    return (false);
    }
    else
    { DBG_PRINT("Initialized QSPI Flash device\r\n");
    }
    //
    // Initialize FileX system with LevelX:
    //
    ret = CFileX_IniLevelX(); // The fileX and level X initialization as in the Renesas examples
    if (ret != LX_SUCCESS)
    { DBG_PRINT_ERR("Failed to initialize NOR flash support\r\n");
    return (false);
    }
    //
    // Add this this line only to repair a "rebel" QSPI:
    // (Released firmware SHOULD NOT contain this line!)
    //
    # if (REPAIR_QSPI > 0)
    ret = CQspi_Erase(); // The standard "erase all" as in the Renesas examples
    if (ret == FSP_SUCCESS)
    { //
    // Format the media:
    //
    ret = CFileX_FormatMedia(&CFitxers.FxMedia); // See code below
    if (ret == FSP_SUCCESS)
    { DBG_PRINT("Erasing and formatting QSPI Flash device successful.\r\n");
    }
    }
    # endif

    ...
    }


    UINT CFileX_FormatMedia(FX_MEDIA *pMedia)
    { UINT status;
    //
    // If open, close media before format:
    //
    status = fx_media_close(pMedia);
    if ((status != FX_SUCCESS) &&
    (status != FX_MEDIA_NOT_OPEN) // <-- That's OK
    ){ DBG_PRINT_ERR("Media close failed");
    }
    //
    // Format QSPI Flash:
    //
    DBG_PRINT("Formatting media (QSPI Flash memory)\r\n");
    status = fx_media_format
    ( pMedia, // Pointer to FileX media control block.
    RM_FILEX_LEVELX_NOR_DeviceDriver, // Driver entry
    (void*)&g_rm_filex_levelx_nor0_instance, // Pointer to LevelX NOR Driver
    mb_FxMediaSector, // Media buffer pointer
    sizeof(mb_FxMediaSector), // Media buffer size
    (char *)G_FX_MEDIA0_VOLUME_NAME, // Volume Name
    G_FX_MEDIA0_NUMBER_OF_FATS, // Number of FATs
    G_FX_MEDIA0_DIRECTORY_ENTRIES, // Directory Entries
    G_FX_MEDIA0_HIDDEN_SECTORS, // Hidden sectors
    G_FX_MEDIA0_TOTAL_SECTORS, // Total sectors
    G_FX_MEDIA0_BYTES_PER_SECTOR, // Sector size
    G_FX_MEDIA0_SECTORS_PER_CLUSTER, // Sectors per cluster
    MEDIA_SECTOR_HEADS_VALUE, // Heads (disk media)
    MEDIA_SECTORS_PER_HEAD // Sectors per track (disk media)
    );

    if (status != FX_SUCCESS)
    { DBG_PRINT_ERR("Media Format failed!\r\n");
    }
    else
    { DBG_PRINT("Media Format successful.\r\n");
    }

    return status;
    } // CFileX_FormatMedia

  • I've figured out the problem, it was a function call sequence issue related to FileX and LevelX. The proper function call order should be:

    1. Setup QSPI flash.
    2. Call lx_nor_flash_initialize.
    3. Call fx_system_initialize.
    4. Format QSPI flash (if first time running or formatting in general).
    5. Call fx_media_format (if first time running or formatting in general).
    6. Call lx_nor_flash_open.
    7. Call fx_media_open.

    Where I mistakenly was trying to call lx_nor_flash_open before fx_media_format.