查看: 141|回复: 4

[求助] 关于RT1061使用ROM API读写外部QSPI norflash的问题

[复制链接]

该用户从未签到

1

主题

6

帖子

0

注册会员

Rank: 2

积分
77
最后登录
2025-8-12
发表于 2025-8-5 11:14:12 | 显示全部楼层 |阅读模式
本帖最后由 eefocus_4035622 于 2025-8-5 11:17 编辑

目的是做个IAP,网上找资料看到了痞子衡的帖子,于是按照大佬的方式尝试,发现只要涉及到操作FLASH接口就卡住了。求好心大佬帮忙看一下。
原帖地址:想在i.MXRT上搞IAP,岂能放过这个ROM API? - i.MX RT - 恩智浦技术社区
RT1061+MX25L3233FM2I-08G,接口如下:
查了接口方式,是FlexSPI PORTA
我在SDK目录下\boards\evkmimxrt1060\driver_examples\fsl_romapi找个了例程,把main的主要代码抄了过来,代码如下。目前程序是XIP在0x60000000运行,测试操作在0x60300000.
程序卡在ROM_FLEXSPI_NorFlash_GetConfig

/*******************************************************************************
* Definitions
******************************************************************************/
#define FlexSpiInstance           0U
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
#define FLASH_SIZE                0x400000UL /* 4MBytes */
#define FLASH_PAGE_SIZE           256UL      /* 256Bytes */
#define FLASH_SECTOR_SIZE         0x1000UL   /* 4KBytes */
#define FLASH_BLOCK_SIZE          0x10000UL  /* 64KBytes */
#define BUFFER_LEN FLASH_PAGE_SIZE
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief config serial NOR option  */
static serial_nor_config_option_t option = {
    .option0.U = 0xc0000007U,
    .option1.U = 0U,
};

/*! @brief FLEXSPI NOR flash driver Structure */
static flexspi_nor_config_t norConfig;
/*! @brief Buffer for program */
static uint8_t s_buffer[BUFFER_LEN];
/*! @brief Buffer for readback */
static uint8_t s_buffer_rbc[BUFFER_LEN];
status_t FLEXSPI_NorFlash_GetVendorID(uint32_t instance, uint32_t *vendorID);


void fun_romapitest()
{
                status_t status;
    uint32_t i        = 0U;
    uint32_t vendorID = 0U;
    uint32_t serialNorAddress;        /* Address of the serial nor device location */
    uint32_t FlexSPISerialNorAddress; /* Address of the serial nor device in FLEXSPI memory */
    uint32_t serialNorTotalSize;
    uint32_t serialNorSectorSize;
    uint32_t serialNorPageSize;

                PRINTF("\r\n FLEXSPI NOR example started!\r\n");
    /* Clean up FLEXSPI NOR flash driver Structure */
    memset(&norConfig, 0U, sizeof(flexspi_nor_config_t));

    /* Disable I cache */
    SCB_DisableICache();

    /* Setup FLEXSPI NOR Configuration Block */
    status = ROM_FLEXSPI_NorFlash_GetConfig(FlexSpiInstance, &norConfig, &option);
    if (status == kStatus_Success)
    {
        PRINTF("\r\n Successfully get FLEXSPI NOR configuration block\r\n ");
    }
    else
    {
        PRINTF("\r\n Get FLEXSPI NOR configuration block failure!\r\n");
        return;
    }

    /* Initializes the FLEXSPI module for the other FLEXSPI APIs */
    status = ROM_FLEXSPI_NorFlash_Init(FlexSpiInstance, &norConfig);
    if (status == kStatus_Success)
    {
        PRINTF("\r\n Successfully init FLEXSPI serial NOR flash\r\n ");
    }
    else
    {
        PRINTF("\r\n Erase sector failure !\r\n");
        return;
    }

    /* Perform software reset after initializing flexspi module */
    ROM_FLEXSPI_NorFlash_ClearCache(FlexSpiInstance);

    /*  Probe device presence by verifying Manufacturer ID */
    status = FLEXSPI_NorFlash_GetVendorID(FlexSpiInstance, &vendorID);
    if (status == kStatus_Success)
    {
        PRINTF("\r\n Serial NOR flash has been found successfully\r\n ");
        PRINTF("Vendor ID: 0x%x\r\n", vendorID);
    }
    else
    {
        PRINTF("\r\n Serial flash can not be found!\r\n");
        return;
    }

    serialNorTotalSize  = norConfig.memConfig.sflashA1Size;
    serialNorSectorSize = norConfig.sectorSize;
    serialNorPageSize   = norConfig.pageSize;

    /* Enable I cache */
    SCB_EnableICache();

    /* Print serial NOR flash information */
    PRINTF("\r\n Serial NOR flash Information: ");
    PRINTF("\r\n Total program flash size:\t%d KB, Hex: (0x%x)", (serialNorTotalSize / 1024U), serialNorTotalSize);
    PRINTF("\r\n Program flash sector size:\t%d KB, Hex: (0x%x) ", (serialNorSectorSize / 1024U), serialNorSectorSize);
    PRINTF("\r\n Program flash page size:\t%d B, Hex: (0x%x)\r\n", serialNorPageSize, serialNorPageSize);

/*
* SECTOR_INDEX_FROM_END = 1 means the last sector,
* SECTOR_INDEX_FROM_END = 2 means (the last sector - 1) ...
*/
#ifndef SECTOR_INDEX_FROM_END
#define SECTOR_INDEX_FROM_END 1U
#endif
    /* Erase a sector from target device dest address */
    serialNorAddress        = serialNorTotalSize - (SECTOR_INDEX_FROM_END * serialNorSectorSize);
    FlexSPISerialNorAddress = EXAMPLE_FLEXSPI_AMBA_BASE + serialNorAddress;

    /* Erase one sector. */
    PRINTF("\r\n Erasing serial NOR flash over FLEXSPI");
    status = ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, 0x60300000, 0x1000);
    if (status == kStatus_Success)
    {
        /* Print message for user. */
        PRINTF("\r\n Successfully erased one sector of NOR flash device 0x%x -> 0x%x\r\n", serialNorAddress,
               (serialNorAddress + serialNorSectorSize));
    }
    else
    {
        PRINTF("\r\n Erase sector failure!\r\n");
                                return;
    }

    PRINTF("\r\n Program a buffer to a page of NOR flash");
    /* Prepare user buffer. */
    for (i = 0; i < BUFFER_LEN; i++)
    {
        s_buffer = i;
    }

    /* Program user buffer into FLEXSPI NOR flash */
    status =
        ROM_FLEXSPI_NorFlash_ProgramPage(FlexSpiInstance, &norConfig, 0x60300000, (const uint32_t *)s_buffer);
    if (status != kStatus_Success)
    {
        PRINTF("\r\n Page program failure!\r\n");
        return;
    }

    DCACHE_InvalidateByRange(FlexSPISerialNorAddress, sizeof(s_buffer_rbc));
    /* Verify programming by reading back from FLEXSPI memory directly */
    memcpy(s_buffer_rbc, (void *)(FlexSPISerialNorAddress), sizeof(s_buffer_rbc));
    if (memcmp(s_buffer_rbc, s_buffer, sizeof(s_buffer)) == 0)
    {
        PRINTF("\r\n Successfully programmed and verified location FLEXSPI memory 0x%x -> 0x%x \r\n",
               (FlexSPISerialNorAddress), (FlexSPISerialNorAddress + sizeof(s_buffer)));
    }
    else
    {
        PRINTF("\r\n Program data -  read out data value incorrect!\r\n ");
        return;
    }

    /* Erase the context we have progeammed before*/
//    status = ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, serialNorAddress, serialNorSectorSize);

    PRINTF("\r\n End of FLEXSPI NOR Example! \r\n");;
}

引脚

引脚

接口

接口
回复

使用道具 举报

该用户从未签到

1

主题

6

帖子

0

注册会员

Rank: 2

积分
77
最后登录
2025-8-12
 楼主| 发表于 2025-8-5 11:53:51 | 显示全部楼层
XIP文件夹下evkmimxrt1060_flexspi_nor_config.c中的LUTS配置如下
.memConfig =
        {
            .tag                  = FLEXSPI_CFG_BLK_TAG,
            .version              = FLEXSPI_CFG_BLK_VERSION,
            .readSampleClkSrc     = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
            .csHoldTime           = 3u,
            .csSetupTime          = 3u,
            .controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable),
            .deviceType           = kFlexSpiDeviceType_SerialNOR,
            .sflashPadType        = kSerialFlash_4Pads,
            .serialClkFreq        = kFlexSpiSerialClk_120MHz,
            .sflashA1Size         = 4u * 1024u * 1024u,
            .lookupTable =
                {
                    // Read LUTs
                    [0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
                    [1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),

                    // Read Status LUTs
                    [4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),
                                                                       
                    // Write Enable LUTs
                    [4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0),

                    // Erase Sector LUTs
                    [4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18),

                    // Erase Block LUTs
                    [4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18),

                    // Pape Program LUTs
                    [4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),
                    [4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),

                    // Erase Chip LUTs
                    [4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0),
                                                                               
//                                                                                /* 00 - 标准读取命令 (SPI 模式) 7*/
//                                                                                //[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
//                                                                                [4 * 7] =
//                                                                                                FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x03, READ_SDR, FLEXSPI_1PAD, 0x18),
//                                                                               
//                                                                                /* 01 - 快速读取命令 (SPI 模式) */
//                                                                                //[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
//                                                                                [4 * 13] =
//                                                                                                FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0B, RADDR_SDR, FLEXSPI_1PAD, 0x18) |
//                                                                                                FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 0x04, READ_SDR, FLEXSPI_1PAD, 0x04),
                                                                               
                                                                //    /* 02 - 快速读取双输出命令 (Dual SPI 模式) */
                                                                //    [4 * kFLEXSPI_CommandIndex_ReadFastDual] =
                                                                //        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x3B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18) |
                                                                //        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_READ_SDR, kFLEXSPI_2PAD, 0x04),
                                                                               
//                                                                                /* 03 - 快速读取四输出命令 (Quad SPI 模式) */
//                                                                                [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
//                                                                                                FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x6B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18) |
//                                                                                                FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
                                                                               
                                                                                /* 13 - 读取设备 ID */
                                                                                [4 * 12] =
                                                                                                FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x9F, READ_SDR, FLEXSPI_1PAD, 0x04) |
                                                                                                FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x04, READ_SDR, FLEXSPI_1PAD, 0x04),
                                                                               
//                                                                                /* 14 - 使能四字节地址模式 */
//                                                                                [4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =
//                                                                                                FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xB7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
//                                                                               
//                                                                                /* 15 - 禁用四字节地址模式 */
//                                                                                [4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =
//                                                                                                FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xE9, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
                                                                               
                },
回复 支持 反对

使用道具 举报

  • TA的每日心情
    擦汗
    昨天 00:18
  • 签到天数: 2394 天

    连续签到: 103 天

    [LV.Master]伴坛终老

    84

    主题

    2万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22238
    最后登录
    2025-8-12
    发表于 2025-8-5 15:26:26 | 显示全部楼层
    看了下,这个主要注意链接引脚是否匹配,flash配置参数,以及堆栈空间大小吧
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    昨天 00:18
  • 签到天数: 2394 天

    连续签到: 103 天

    [LV.Master]伴坛终老

    84

    主题

    2万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22238
    最后登录
    2025-8-12
    发表于 2025-8-5 15:30:48 | 显示全部楼层
    .option0.U = 0xc0000007U这个是7还是8

    点评

    查了配置,5比较合适  发表于 7 天前
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-13 03:14 , Processed in 0.094304 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表