硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3873|回复: 3
收起左侧

[SPI/QSPI] STM32H750的QSPI复位W25Q128JV时,查询状态寄存器始终超时

[复制链接]

24

主题

70

回帖

142

积分

初级会员

积分
142
发表于 2019-1-14 10:14:08 | 显示全部楼层 |阅读模式
环境:STM32H750,QSPI,W25Q128JV,IAR,JLINK

//QSPI初始化
static void MX_QUADSPI_Init(void)
{

  /* USER CODE BEGIN QUADSPI_Init 0 */

  /* USER CODE END QUADSPI_Init 0 */

  /* USER CODE BEGIN QUADSPI_Init 1 */

  /* USER CODE END QUADSPI_Init 1 */
  /* QUADSPI parameter configuration*/
  hqspi.Instance = QUADSPI;
  hqspi.Init.ClockPrescaler = 1;
  hqspi.Init.FifoThreshold = 4;
  hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
  hqspi.Init.FlashSize = 23;
  hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE;
  hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
  hqspi.Init.FlashID = QSPI_FLASH_ID_1;
  hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
  if (HAL_QSPI_Init(&hqspi) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN QUADSPI_Init 2 */

  /* USER CODE END QUADSPI_Init 2 */

}


/**
  * @brief  读取存储器的SR并等待EOP
  * @param  qspiFlash: QSPI句柄
  * @param  Timeout 超时
  * @retval 无
  */
static uint8_t QSPI_AutoPollingMemReady(uint32_t Timeout)
{
    QSPI_CommandTypeDef     s_command;
    QSPI_AutoPollingTypeDef s_config;


    /* 配置自动轮询模式等待存储器准备就绪 */
    s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
    s_command.AddressSize          = QSPI_ADDRESS_24_BITS;
    s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
    s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
    s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
    s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
    s_command.Instruction       = READ_STATUS_REG1_CMD;
    s_command.AddressMode       = QSPI_ADDRESS_NONE;
    s_command.DataMode          = QSPI_DATA_1_LINE;
    s_command.DummyCycles       = 0;

    s_config.Match           = 0x00;
    s_config.Mask            = W25Q128FV_FSR_BUSY;
    s_config.MatchMode       = QSPI_MATCH_MODE_AND;
    s_config.StatusBytesSize = 1;
    s_config.Interval        = 0x20;
    s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;

    if (HAL_QSPI_AutoPolling(&qspiFlash, &s_command, &s_config, Timeout) != HAL_OK)
        return QSPI_ERROR;

    return QSPI_OK;
}





//复位QSPI存储器。
static uint8_t QSPI_ResetMemory()
{
    QSPI_CommandTypeDef s_command;

    /* 初始化复位使能命令 */
    s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
    s_command.AddressSize          = QSPI_ADDRESS_24_BITS;
    s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
    s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
    s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
    s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
    s_command.Instruction       = RESET_ENABLE_CMD;
    s_command.AddressMode       = QSPI_ADDRESS_NONE;
    s_command.DataMode          = QSPI_DATA_NONE;
    s_command.DummyCycles       = 0;


    /* 发送命令 */
    if (HAL_QSPI_Command(&qspiFlash, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
        return QSPI_ERROR;

    /* 发送复位存储器命令 */
    s_command.Instruction = RESET_MEMORY_CMD;
    if (HAL_QSPI_Command(&qspiFlash, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
        return QSPI_ERROR;

    bsp_Delayus(100);

    /* 配置自动轮询模式等待存储器就绪 */
    if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
        return QSPI_ERROR;

    return QSPI_OK;
}




/**
  * @brief  初始化QSPI存储器
  * @retval QSPI存储器状态
  */
uint8_t BSP_QSPI_Init(void)
{
    QSPI_CommandTypeDef s_command;
    uint8_t value = W25Q128FV_FSR_QE;


    /* QSPI存储器复位 */
    if (QSPI_ResetMemory() != QSPI_OK)
        return QSPI_NOT_SUPPORTED;

    /* 使能写操作 */
    if (QSPI_WriteEnable() != QSPI_OK)
        return QSPI_ERROR;

    /* 设置四路使能的状态寄存器,使能四通道IO2和IO3引脚 */
    s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
    s_command.AddressSize          = QSPI_ADDRESS_24_BITS;
    s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
    s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
    s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
    s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
    s_command.Instruction       = WRITE_STATUS_REG2_CMD;
    s_command.AddressMode       = QSPI_ADDRESS_NONE;
    s_command.DataMode          = QSPI_DATA_1_LINE;
    s_command.DummyCycles       = 0;
    s_command.NbData            = 1;


    /* 配置命令 */
    if (HAL_QSPI_Command(&qspiFlash, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
        return QSPI_ERROR;

    /* 传输数据 */
    if (HAL_QSPI_Transmit(&qspiFlash, &value, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
        return QSPI_ERROR;

    /* 自动轮询模式等待存储器就绪 */
    if (QSPI_AutoPollingMemReady(W25Q128FV_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
        return QSPI_ERROR;

    return QSPI_OK;
}
回复

使用道具 举报

24

主题

70

回帖

142

积分

初级会员

积分
142
 楼主| 发表于 2019-1-14 10:17:19 | 显示全部楼层
  if (HAL_QSPI_AutoPolling(&qspiFlash, &s_command, &s_config, Timeout) != HAL_OK)
        return QSPI_ERROR;
这里始终执行超时
回复

使用道具 举报

24

主题

70

回帖

142

积分

初级会员

积分
142
 楼主| 发表于 2019-1-14 11:23:45 | 显示全部楼层
utyang 发表于 2019-1-14 10:17
if (HAL_QSPI_AutoPolling(&qspiFlash, &s_command, &s_config, Timeout) != HAL_OK)
        return QS ...

问题找到了,代码没问题,时钟达不到这么高频率,硬件设计有限制,实测时钟只能达到30M
回复

使用道具 举报

36

主题

1446

回帖

1554

积分

至尊会员

积分
1554
发表于 2019-8-13 14:53:14 | 显示全部楼层
utyang 发表于 2019-1-14 11:23
问题找到了,代码没问题,时钟达不到这么高频率,硬件设计有限制,实测时钟只能达到30M

你这个应该是GPIO速度设置的不合适导致的,cube生成的代码这块有点小问题,修改告诉之后能跑带100M
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-17 17:29 , Processed in 0.246458 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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