打印
[STM32H7]

【STM32H7S78-DK测评】扩展内存,PSRAM映射实验

[复制链接]
1502|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
【STM32H7S78-DK测评】扩展内存,PSRAM映射实验

在嵌入式项目里面,集成到MCU中的SRAM一般很小。在大多数应用项目里片上的SRAM都可以满足项目需求的,不过,当像本次DIY的STM32H7S78-DK评估板中有一个高分辨率的大展时,片上的620KB的SRAM就有点微不足道了。当然,ST官方也贴心地提供了完美解决方案:板载了一块容量高达256-Mbit的PSRAM。不过,强大的STM32H7S78使用了Hex-SPI的外设接口,超级快的外设接口,它的性能如何?是否实用呢?今天我就带大家来验证一下!

前面两个帖子有讲过,STM32H7S78采用了BootFllash的程序架构,我们一般仅编写App程序即可,但本次实验的内容是在Boot程序中配置并实现的,因此,我们的工程也仅有Boot程序。接下来,我们构建验证PSRAM的例程。

  • 我们先初始化Hex-SPI外设及PSRAM的配置参数,完成内存映射;
  • 生成一个数组,预先初始化好我们的数据;
  • 将数组的内容写入到指定地址(映射的地址0x90000000);
  • 将指定地址的数据内容回读;
  • 与写入数据两者比较,如果一致,则打印“校对成功”的调试字符;

分享一下PSRAM的初始化配置代码及数据比较代码:

uint32_t APS256_WriteReg(XSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t *Value)
{
  XSPI_RegularCmdTypeDef sCommand1={0};
  
  /* Initialize the write register command */
  sCommand1.OperationType      = HAL_XSPI_OPTYPE_COMMON_CFG;
  sCommand1.InstructionMode    = HAL_XSPI_INSTRUCTION_8_LINES;
  sCommand1.InstructionWidth    = HAL_XSPI_INSTRUCTION_8_BITS;
  sCommand1.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
  sCommand1.Instruction        = WRITE_REG_CMD;
  sCommand1.AddressMode        = HAL_XSPI_ADDRESS_8_LINES;
  sCommand1.AddressWidth        = HAL_XSPI_ADDRESS_32_BITS;
  sCommand1.AddressDTRMode     = HAL_XSPI_ADDRESS_DTR_ENABLE;
  sCommand1.Address            = Address;
  sCommand1.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
  sCommand1.DataMode           = HAL_XSPI_DATA_8_LINES;
  sCommand1.DataDTRMode        = HAL_XSPI_DATA_DTR_ENABLE;
  sCommand1.DataLength         = 2;
  sCommand1.DummyCycles        = 0;
  sCommand1.DQSMode            = HAL_XSPI_DQS_DISABLE;
  
  /* Configure the command */
  if (HAL_XSPI_Command(Ctx, &sCommand1, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return HAL_ERROR;
  }
  
  /* Transmission of the data */
  if (HAL_XSPI_Transmit(Ctx, (uint8_t *)(Value), HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return HAL_ERROR;
  }
  
  return HAL_OK;
}

/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  Read mode register value
* @param  Ctx Component object pointer
* @param  Address Register address
* @param  Value Register value pointer
* @param  LatencyCode Latency used for the access
* @retval error status
*/
uint32_t APS256_ReadReg(XSPI_HandleTypeDef *Ctx, uint32_t Address, uint8_t *Value, uint32_t LatencyCode)
{
  XSPI_RegularCmdTypeDef sCommand={0};
  
  /* Initialize the read register command */
  sCommand.OperationType      = HAL_XSPI_OPTYPE_COMMON_CFG;
  sCommand.InstructionMode    = HAL_XSPI_INSTRUCTION_8_LINES;
  sCommand.InstructionWidth    = HAL_XSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
  sCommand.Instruction        = READ_REG_CMD;
  sCommand.AddressMode        = HAL_XSPI_ADDRESS_8_LINES;
  sCommand.AddressWidth        = HAL_XSPI_ADDRESS_32_BITS;
  sCommand.AddressDTRMode     = HAL_XSPI_ADDRESS_DTR_ENABLE;
  sCommand.Address            = Address;
  sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
  sCommand.DataMode           = HAL_XSPI_DATA_8_LINES;
  sCommand.DataDTRMode        = HAL_XSPI_DATA_DTR_ENABLE;
  sCommand.DataLength            = 2;
  sCommand.DummyCycles        = (LatencyCode - 1U);
  sCommand.DQSMode            = HAL_XSPI_DQS_ENABLE;
  
  /* Configure the command */
  if (HAL_XSPI_Command(Ctx, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return HAL_ERROR;
  }
  
  /* Reception of the data */
  if (HAL_XSPI_Receive(Ctx, (uint8_t *)Value, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return HAL_ERROR;
  }
  
  return HAL_OK;
}

/**
* @brief  Switch from Octal Mode to Hexa Mode on the memory
* @param  None
* @retval None
*/
static void Configure_APMemory(void)
{
  /* MR0 register for read and write */
  uint8_t regW_MR0[2]={0x24,0x8D}; /* To configure AP memory Latency Type and drive Strength */
  uint8_t regR_MR0[2]={0};
  
  /* MR8 register for read and write */
  uint8_t regW_MR8[2]={0x4B,0x08}; /* To configure AP memory Burst Type */
  uint8_t regR_MR8[2]={0};
  
  /*Read Latency */
  uint8_t latency=6;
  
  /* Configure Read Latency and drive Strength */
  if (APS256_WriteReg(&hxspi1, MR0, regW_MR0) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Check MR0 configuration */
  if (APS256_ReadReg(&hxspi1, MR0, regR_MR0, latency ) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Check MR0 configuration */
  if (regR_MR0 [0] != regW_MR0 [0])
  {
    Error_Handler() ;
  }
  
  /* Configure Burst Length */
  if (APS256_WriteReg(&hxspi1, MR8, regW_MR8) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Check MR8 configuration */
  if (APS256_ReadReg(&hxspi1, MR8, regR_MR8, 6) != HAL_OK)
  {
    Error_Handler();
  }
  
  if (regR_MR8[0] != regW_MR8[0])
  {
    Error_Handler() ;
  }
}

static void MX_XSPI1_Init(void)
{

  /* USER CODE BEGIN XSPI1_Init 0 */

  /* USER CODE END XSPI1_Init 0 */

  XSPIM_CfgTypeDef sXspiManagerCfg = {0};

  /* USER CODE BEGIN XSPI1_Init 1 */

  /* USER CODE END XSPI1_Init 1 */
  /* XSPI1 parameter configuration*/
  hxspi1.Instance = XSPI1;
  hxspi1.Init.FifoThresholdByte = 4;
  hxspi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
  hxspi1.Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM_16BITS;
  hxspi1.Init.MemorySize = HAL_XSPI_SIZE_64MB;
  hxspi1.Init.ChipSelectHighTimeCycle = 1;
  hxspi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
  hxspi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
  hxspi1.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED;
  hxspi1.Init.ClockPrescaler = 0;
  hxspi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;
  hxspi1.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE;
  hxspi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE;
  hxspi1.Init.MaxTran = 0;
  hxspi1.Init.Refresh = 0;
  hxspi1.Init.MemorySelect = HAL_XSPI_CSSEL_NCS1;
  if (HAL_XSPI_Init(&hxspi1) != HAL_OK)
  {
    Error_Handler();
  }
  sXspiManagerCfg.nCSOverride = HAL_XSPI_CSSEL_OVR_NCS1;
  sXspiManagerCfg.IOPort = HAL_XSPIM_IOPORT_1;
  if (HAL_XSPIM_Config(&hxspi1, &sXspiManagerCfg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN XSPI1_Init 2 */

  /* USER CODE END XSPI1_Init 2 */

}

看看比对结果!一次成功!



其实,像这种评估板,如果比较失败,则可以肯定是咱们自己的xspi的配置参数出现了错误。开发板本身不会出现问题!这也是原型验证的必要之处吧!——软件、硬件,两者总得有一个是靠谱的吧!




使用特权

评论回复
沙发
k2715009743| | 2024-10-16 09:10 | 只看该作者

使用特权

评论回复
板凳
sukermyz| | 2024-10-23 22:12 | 只看该作者
非常赞的资料。

使用特权

评论回复
地板
Amazingxixixi| | 2024-10-31 16:20 | 只看该作者
学习一下如何修改

使用特权

评论回复
5
jobszheng|  楼主 | 2024-10-31 16:44 | 只看该作者

这个过程倒是没有啥。
就是读datasheet的过程太煎熬了

使用特权

评论回复
6
suncat0504| | 2024-10-31 17:29 | 只看该作者
能扩展内存,性能确实强。有了扩展内存,方便做图像类的处理了。谢谢分享,学习了。

使用特权

评论回复
7
地瓜patch| | 2024-10-31 18:54 | 只看该作者
这个映射不是必须的,什么情况下要考虑映射

使用特权

评论回复
8
jobszheng|  楼主 | 2024-11-1 16:48 | 只看该作者
地瓜patch 发表于 2024-10-31 18:54
这个映射不是必须的,什么情况下要考虑映射

这款MCU的片上资源非常有限。
所以基本上一定要使用外扩的资源,如外扩的RAM与Flash

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:热爱开源,乐于分享。在嵌入式技术领域里面,主攻通讯协议,Modbus,TCP/IP以及虚拟化和RTOS

16

主题

364

帖子

2

粉丝