jobszheng 发表于 2024-10-14 01:42

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

【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;
}

/**
* @briefRead mode register value
* @paramCtx Component object pointer
* @paramAddress Register address
* @paramValue Register value pointer
* @paramLatencyCode 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;
}

/**
* @briefSwitch from Octal Mode to Hexa Mode on the memory
* @paramNone
* @retval None
*/
static void Configure_APMemory(void)
{
/* MR0 register for read and write */
uint8_t regW_MR0={0x24,0x8D}; /* To configure AP memory Latency Type and drive Strength */
uint8_t regR_MR0={0};

/* MR8 register for read and write */
uint8_t regW_MR8={0x4B,0x08}; /* To configure AP memory Burst Type */
uint8_t regR_MR8={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 != regW_MR0 )
{
    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 != regW_MR8)
{
    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

学习一下如何修改

jobszheng 发表于 2024-10-31 16:44

Amazingxixixi 发表于 2024-10-31 16:20
学习一下如何修改

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

suncat0504 发表于 2024-10-31 17:29

能扩展内存,性能确实强。有了扩展内存,方便做图像类的处理了。谢谢分享,学习了。

地瓜patch 发表于 2024-10-31 18:54

这个映射不是必须的,什么情况下要考虑映射

jobszheng 发表于 2024-11-1 16:48

地瓜patch 发表于 2024-10-31 18:54
这个映射不是必须的,什么情况下要考虑映射

这款MCU的片上资源非常有限。
所以基本上一定要使用外扩的资源,如外扩的RAM与Flash
页: [1]
查看完整版本: 【STM32H7S78-DK测评】扩展内存,PSRAM映射实验