ST意法半导体
直播中

王婷

7年用户 989经验值
私信 关注
[问答]

怎样去解决QSPI从STM32F7迁移到STM32H7失败的问题

我被要求查看我们从 STM32F7 迁移到 STM32H7 时遇到的问题。我们在与 QUAD SPI 芯片 (Micron MT25QL256ABA) 通信时遇到问题。
(我对 SPI 通信和微控制器非常熟悉,但对 STM32 还是陌生的。)
但是老实说,我仍然在学习这个芯片的曲线。
我们有一个示例程序,可以将数据写入 QSPI,然后在 MemoryMappedMode 中将其读回。奇怪的是,该程序运行了 5 次测试,然后未能读回数据进行比较。这是始终失败的代码部分:
  •         // +++++++ START MULti-SECTOR TEST ++++++++++
  •         // Erase a sector then write a sector
  •         // Notes: EraseSector command may be size dependent.
  •         //        EndAddress parameter is ignored.
  •         // Need to re-init to exit Memory Mapped Mode from previous test
  •         CSP_QUADSPI_Init();
  •         for (var = 0; var < SECTOR_COUNT; var++)
  •         {
  •                 if (CSP_QSPI_EraseSector(var * MEMORY_SECTOR_SIZE,
  •                                 (var + 1) * MEMORY_SECTOR_SIZE - 1) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected
  •                 }
  •                 Wait_For_QUADSPI();
  •                 if (CSP_QSPI_WriteMemory(upCountBuffer, var * MEMORY_SECTOR_SIZE,
  •                                 sizeof(upCountBuffer)) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected
  •                 }
  •                 if (CSP_QSPI_EraseSector(0x1000000 + (var * MEMORY_SECTOR_SIZE),
  •                                 0x1000000 + (var * MEMORY_SECTOR_SIZE) + (MEMORY_SECTOR_SIZE - 1)) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected
  •                 }
  •                 Wait_For_QUADSPI();
  •                 if (CSP_QSPI_WriteMemory(downCountBuffer, 0x1000000 + (var * MEMORY_SECTOR_SIZE),
  •                                 sizeof(downCountBuffer)) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected
  •                 }
  •          }
  •         if (CSP_QSPI_EnableMemoryMappedMode() != HAL_OK)
  •         {
  •                 while (1); //breakpoint - error detected
  •         }
  •         HAL_Delay(10);
  •         //Wait_For_QUADSPI();
  •         // xxCountBuffer[] (size of one sector) is bulk compared against a written sector.
  •         // This comparison occurs, sector by sector for SECTOR_COUNT number of times.
  •         for (var = 0; var < SECTOR_COUNT; var++)
  •         {
  •                 memcpy( upCountBuffer_read,
  •                                 (uint8_t*) (0x90000000 + (var * MEMORY_SECTOR_SIZE)), MEMORY_SECTOR_SIZE);
  •                 if (memcmp(upCountBuffer, upCountBuffer_read, MEMORY_SECTOR_SIZE) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected - otherwise QSPI works properly
  •                 }
  •                 if (memcmp(upCountBuffer,
  •                                 (uint8_t*) (0x90000000 + (var * MEMORY_SECTOR_SIZE)),
  •                                 MEMORY_SECTOR_SIZE) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected - otherwise QSPI works properly
  •                 }
  •                 memcpy( downCountBuffer_read,
  •                                 (uint8_t*) (0x90000000 + 0x1000000 + (var * MEMORY_SECTOR_SIZE)),
  •                                 MEMORY_SECTOR_SIZE);
  •                 if (memcmp(downCountBuffer, downCountBuffer_read, MEMORY_SECTOR_SIZE) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected - otherwise QSPI works properly
  •                 }
  •                 if (memcmp(downCountBuffer,
  •                                 (uint8_t*) (0x90000000 + 0x1000000 + (var * MEMORY_SECTOR_SIZE)),
  •                                 MEMORY_SECTOR_SIZE) != HAL_OK)
  •                 {
  •                         while (1);  //breakpoint - error detected - otherwise QSPI works properly
  •                 }
  •         }
注意 Wait_For_QUADSPI() 如下:
  • void Wait_For_QUADSPI(void)
  • {
  •         HAL_Delay(10);
  •         int count = 0;
  •         HAL_QSPI_StateTypeDef iState;
  • //return;
  •         while (1)
  •         {
  •                 iState = HAL_QSPI_GetState(&hqspi);
  •                 switch (iState)
  •                 {
  •                 case HAL_QSPI_STATE_RESET:
  •                         break;
  •                 case HAL_QSPI_STATE_READY:
  •                         return;
  •                 case HAL_QSPI_STATE_BUSY:
  •                         break;
  •                 case HAL_QSPI_STATE_BUSY_INDIRECT_TX:
  •                         break;
  •                 case HAL_QSPI_STATE_BUSY_INDIRECT_RX:
  •                         break;
  •                 case HAL_QSPI_STATE_BUSY_AUTO_POLLING:
  •                         break;
  •                 case HAL_QSPI_STATE_BUSY_MEM_MAPPED:
  •                         count++;
  •                         if (count>10)
  •                         {
  •                                 //HAL_QSPI_Abort(&hqspi);/// do I need to reinit?
  •                                 return;
  •                         }
  •                         break;
  •                 case HAL_QSPI_STATE_ABORT:
  •                         break;
  •                 case HAL_QSPI_STATE_ERROR:
  •                         break;
  •                 default:
  •                         break;
  •                 }
  •                 HAL_Delay(10);
  •         }
  • }
在以前的测试中,如果我在 EnableMemoryMappedMode 之后调用上述函数,它会挂起,所以我尝试中止,但这没有帮助。所以我注释掉了那部分,现在在启用内存映射模式后使用 10 毫秒的硬编码延迟。
这是 EnableMemoryMappedMode 代码。注意我尝试启用和不启用超时。
  • uint8_t CSP_QSPI_EnableMemoryMappedMode(void) {
  •         QSPI_CommandTypeDef sCommand;
  •         QSPI_MemoryMappedTypeDef sMemMappedCfg;
  •         /* Enable Memory-Mapped mode-------------------------------------------------- */
  •         /***** Assuming QUAD MODE is enabled *****/
  •         /***** Assuming 4-byte address mode ******/
  •         sCommand.InstructionMode = QSPI_INSTRUCTION_4_LINES;
  •         //sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
  •         sCommand.AddressSize = QSPI_ADDRESS_32_BITS;
  •         sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  •         sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
  •         sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
  •         sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
  •         sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
  •         sCommand.DataMode = QSPI_DATA_4_LINES;
  •         sCommand.NbData = 1;
  •         sCommand.Address = 0;
  •         //sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
  •         sCommand.Instruction = QUAD_4BYTE_OUT_FAST_READ_CMD;
  •         sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
  •         sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE; ///QSPI_TIMEOUT_COUNTER_DISABLE;  RRS
  •         if (HAL_QSPI_MemoryMapped(&hqspi, &sCommand, &sMemMappedCfg) != HAL_OK) {
  •                 return HAL_ERROR;
  •         }
  •         return HAL_OK;
  • }
不管怎样,我想联系一下,看看是否有其他人遇到类似的问题,并且可以分享一些代码来说明你是如何解决这个问题的(即你是如何实施 Errata pdf 中的建议的。)


回帖(1)

尤两畅

2022-12-14 10:07:51
对于这个特定案例,我的问题是我需要添加 10 个虚拟循环。(QSPI 芯片的文档说要使用 0 个虚拟周期,但 H7 出于某种原因需要这些周期。)
举报

更多回帖

发帖
×
20
完善资料,
赚取积分