IMX93QSB 的 Flexspi_nor_polling_transfer SDK 示例中的供应商 ID 问题 大家好 我使用适用于 VSCode 的 MCUXpresso 来测试类似 imx93-qsb 的定制板的外围设备。从 SDK 项目 " flexspi_nor_polling_transfer " 开始,我想测试或非闪存 MT25QU01GBBB8E12 的功能,它与示例中使用的芯片非常相似:MT25QU512ABB。 当谈到函数 flexspi_nor_get_vendor_id 时,它给出 0xFF 而不是 0x20,然后它会成功完成最后一次操作。 我使用的是与示例相同的 SPI 外设(SD3 焊盘上的 flexSPI1),我不明白为什么我没有正确读取 ID 供应商。谁能帮帮我? Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 值得一提的是,在扩展 SPI 模式下使用 IS25WX256 时,读 ID 命令 0x9E 也有问题。命令格式为 "FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9e, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 4),"。每次使用时,我都会读到 `0x888cadce`。 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 你好@AldoG、 我试着在 flexspi_nor_get_vendor_id 功能中加入一些 PRINTF 命令,以了解 vendorID 值是怎么回事。 输出结果是这样的 我还尝试将 flashXfer.seqIndex 改为 4 *NOR_CMD_LUT_SEQ_IDX_READID,结果输出发生了变化: 我不知道在功能内部反复推敲是否会有帮助。也许问题出在 seqIndex 值本身。请告诉我您的想法。 此致, 鲍勃 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 您好, ,我发现您使用的正是原样,而不是我建议添加的内容。 我不认为是内存工作不正常,而是获取 ID 的 LUT 命令工作不正常,所以我才提到是否有可能检查发送是否正确。 致以最崇高的敬意/问候, Aldo。 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 你好 我很确定闪存运行良好,因为我已经能够使用这个 UUU 命令放置针对 或非-flash 的引导加载程序: uuu.exe-b qspi imx-启动-imx93-11x11-lpddr4x-evk-sd.bin-flash_singleboot 在 FlexSPI Serial NOR 中设置启动配置,我可以看到引导加载程序运行正常。但我还是不明白,为什么在 MCUXpresso 的 VScode 中使用该项目会出现问题。 如果您能帮助我,请告诉我,我也需要使用 iMX93 的 M33 内核。 谢谢! 鲍勃 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 您好, 感谢您的分享,我会仔细检查的。 同时,您有办法检查硬件上的信号吗? 致以最崇高的敬意/问候, Aldo。 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 你好,阿尔多、 谢谢你帮我。遗憾的是,对 LUT 的更改并不能解决问题,我仍然在 Vendor ID 上读取到 0xff 的值。我与大家分享整个 C 代码: /* * 版权所有 (c) 2016,飞思卡尔半导体有限公司 * 2016-2018 恩智浦版权所有 * 保留所有权利。 * * * SPDX 许可证标识符:BSD-3 条款 */ #include "pin_mux.h" #include "clock_config.h" #include " board.h " #include "fsl_debug_console.h" #include "fsl_rgpio.h" #include "fsl_lpi2c.h" #include "fsl_iomuxc.h" #include "fsl_lpi2c.c" #include "fsl_flexspi.h" #include "app.h" #include "fsl_debug_console.h" #include "fsl_cache.h" #include "pin_mux.h" #include "clock_config.h" #include " board.h " #include "fsl_common.h" /******************************************************************************* * 定义 ******************************************************************************/ /******************************************************************************* * 原型 ******************************************************************************/ /******************************************************************************* * 变量 ******************************************************************************/ /* 程序数据缓冲区应以 4 字节对齐,这样可以避免总线故障,因为此内存区域配置为 MPU 的设备内存。*/ SDK_ALIGN(静态 uint8_t s_nor_program_buffer[256], 4); 静态 uint8_t s_nor_read_buffer[256]; 外部 status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *基, uint32_t 地址); 外部 status_t flexspi_nor_flash_page_program(FLEXSPI_Type *基, uint32_t dstAddr, 常数 uint32_t *src); 外部 status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *基础, uint8_t *vendorId); 外部 status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *基); 外部 status_t flexspi_nor_erase_chip(FLEXSPI_Type *基); 外部 void flexspi_nor_flash_init(FLEXSPI_Type *基); /******************************************************************************* * 代码 ******************************************************************************/ flexspi_device_config_t deviceconfig ={ .flexspiRootClk = 12000000, //12 MHz, ok per noi .闪存大小 = 闪存大小, .CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle, .CSInterval = 2, .CSHoldTime = 3, .CSSetupTime = 3, .数据验证时间 = 0, .列空间 = 0, .启用 WordAddress = 0, .AWRSeqIndex = 0, .AWRSeqNumber = 0, .ARDSeqIndex = nor_cmd_lut_seq_idx_read, .ARDSeqNumber = 1, .AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle, .AHBWriteWaitInterval = 0, }; const uint32_t customLUT[自定义长度] ={ /* 快速读取四通道模式 -SDR */ [4 * nor_cmd_lut_seq_idx_read + 0] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18), [4 * nor_cmd_lut_seq_idx_read + 1] = flexspi_lut_seq( kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x0A, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04), /* 读取状态寄存器 */ [4 * nor_cmd_lut_seq_idx_readstatusreg] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xB5, kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x0), [4 * nor_cmd_lut_seq_idx_readstatusreg + 1] = flexspi_lut_seq(kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), /* 读取 ID */ [4 * nor_cmd_lut_seq_idx_readid] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9E, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),// modifica mia da 0x9F A 0X9E /* 写入启用 4 焊盘 */ [4 * nor_cmd_lut_seq_idx_writeenable_opi] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), /* 启用写入功能 */ [4 * nor_cmd_lut_seq_idx_writeenable] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* 擦除扇区 */ [4 * nor_cmd_lut_seq_idx_erasesector] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18), /* 程序 */ [4 * nor_cmd_lut_seq_idx_pageprogram_quad] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18), [4 * nor_cmd_lut_seq_idx_pageprogram_quad + 1] = flexspi_lut_seq(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x01, kFLEXSPI_Command_STOP, kFLEXSPI_4PAD, 0), /* 进入四重模式 */ [4 * nor_cmd_lut_seq_idx_enablequad] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00), /* 虚拟写入,当 AHB 写入命令触发时,不执行任何操作。*/ [4 * nor_cmd_lut_seq_idx_write] = flexspi_lut_seq(kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0), /* 使用 Qual SDR 读取功能读取状态寄存器 */ [4 * nor_cmd_lut_seq_idx_readstatus_opi] = flexspi_lut_seq(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x02), }; int main(void) { uint32_t i = 0; status_t 状态; uint8_t 供应商 ID = 0; pcal6524_handle_t 句柄; /* 关闭 clang-format */ const clock_root_config_t lpi2cClkCfg ={ .时钟关闭 = false, .mux = 0,// 24MHz 振荡源 .分隔 = 1 }; /* clang-format on */ BOARD_ConfigMPU(); BOARD_InitBootPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); CLOCK_SetRootClock(BOARD_PCAL6524_I2C_CLOCK_ROOT, &lpi2cClkCfg); CLOCK_EnableClock(BOARD_PCAL6524_I2C_CLOCK_GATE); /* 为 M.2 或非闪存卡设置 3.3V */ BOARD_InitPCAL6524(&句柄); PCAL6524_SetDirection(&处理, (1 << BOARD_PCAL6524_EXT1_PWREN), kPCAL6524_Output); PCAL6524_SetPins(&处理, (1 << BOARD_PCAL6524_EXT1_PWREN)); flexspi_nor_flash_init(example_flexspi); PRINTF("\r\nFLEXSPI 示例启动!\r\n"); /* 获取供应商 ID。*/ 状态 = flexspi_nor_get_vendor_id(示例, &vendorID); 如果(status != kStatus_Success) { 返回 状态; } PRINTF("供应商 ID: 0x%x\("......")", vendorID); #if !(定义(xip_external_flash)) /* 擦除整个芯片 .*/ PRINTF("通过 FlexSPI 擦除整个芯片...\r\n"); 状态 = flexspi_nor_erase_chip(example_flexspi); 如果状态 !=kStatus_Success) { 返回状态 } PRINTF("擦除完毕\r\n"); #endif /* 进入四重模式。*/ 状态 = flexspi_nor_enable_quad_mode(example_flexspi); 如果(status != kStatus_Success) { 返回 状态; } /* 擦除扇区。*/ PRINTF (" 通过 FlexSpi 擦除序列号 或非...\ r\n "); 状态 = flexspi_nor_flash_erase_sector(示例, 示例 * SECTOR_SIZE); 如果(status != kStatus_Success) { PRINTF("擦除扇区失败 !\)"); 返回 -1; } memset(s_nor_program_buffer, 0xFFU, ((s_nor_program_buffer)); DCACHE_InvalidateByRange(example_flexspi_amba_base + 示例 * ()()()()()(, flash_page_size); memcpy(s_nor_read_buffer, (void *)(example_flexspi_amba_base + 示例 * SECTOR_SIZE), ((s_nor_read_buffer)); 如果(memcmp(s_nor_program_buffer, s_nor_read_buffer, ((s_nor_program_buffer))) { PRINTF("Erase data - read out data value incorrect !\r\n "); 返回 -1; } 不然 { PRINTF("Erase data - successfully. \r\n"); } 为(i = 0; i < 0xFFU; i++) { s_nor_program_buffer[i] = i; } 状态 = flexspi_nor_flash_page_program(示例, 示例 * SECTOR_SIZE, (空格 *)s_nor_program_buffer); 如果(status != kStatus_Success) { PRINTF("页面程序失败 !\r\n"); 返回 -1; } DCACHE_InvalidateByRange(example_flexspi_amba_base + 示例 * ()()()()()(, flash_page_size); memcpy(s_nor_read_buffer, (void *)(example_flexspi_amba_base + 示例 * SECTOR_SIZE), ((s_nor_read_buffer)); 如果(memcmp(s_nor_read_buffer, s_nor_program_buffer, ((s_nor_program_buffer)) != 0) { PRINTF("程序数据 - 读出数据值不正确 !\r\n "); 返回 -1; } 不然 { PRINTF("程序数据 - 成功。 \r\n"); } 状态 = flexspi_nor_get_vendor_id(示例, &vendorID); 如果(status != kStatus_Success) { 返回 状态; } PRINTF("供应商 ID: 0x%x\("......")", vendorID); PRINTF("状态: %d\,......。", status); 虽然(1) { } } Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 您好, 感谢您的测试,那么很可能是在执行 READ ID 时 LUT 序列不正确,请尝试对 LUT 进行以下更改: /* 读 ID */ [4 * NOR_CMD_LUT_SEQ_IDX_READID] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD,0x9E, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), 请尝试并告知我结果。 致以最崇高的敬意/问候, Aldo。 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 是的,我按照您的建议添加了这段代码: 遗憾的是,正如你所看到的,一切都没有改变: @AldoG你有其他想法吗? 谢谢! 鲍勃 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 您好, hw 上的一切看起来都很好,您能否尝试在数据编程后添加读取供应商 ID 的功能? 致以最崇高的敬意/问候, Aldo。 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 你好,阿尔多、 感谢您的回复。这些是连接 Re: Vendor ID issue in Flexspi_nor_polling_transfer SDK example for IMX93QSB 你好, 这可能是由于没有正确处理SPI内存上的RESET信号造成的,你能分享一下你是如何连接内存的吗? 如果您能提供一个小的原理图,那将会非常有帮助。 致以最崇高的敬意/问候, Aldo。
查看全文