cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with PSRAM peripherals of STM32H735

Lin_Yishan
Associate II

Hello! I use the OSPI2 interface of the STM32H735IGK6 to connect to the ISS66WVO32M8DBLL and use indirect mode for memory reading and writing.
1、The first step is to use cubemx to configure OSPI interface parameters as shown in the following figure:

 

Lin_Yishan_0-1722994715086.png

 

Lin_Yishan_1-1722994714722.png

 

Lin_Yishan_2-1722994715331.png

 

2、The second step is to define the data read and write command parameters with OSPI_RegularCmdTypeDef:

 1.here the write data is 32 bytes and the data is printed out through the serial port

Lin_Yishan_3-1722994715328.png

 

Lin_Yishan_4-1722994715115.png

 

2.here read the 32 bytes of data written above 

Lin_Yishan_5-1722994715220.png

 

Lin_Yishan_6-1722994715128.png

 

3.The following are the address and instruction parameters for the call, as defined by ISS66WVO32M8DBLL:

Use wrap burst mode

Lin_Yishan_7-1722994715222.png

 

Lin_Yishan_8-1722994715318.png

 

Lin_Yishan_9-1722994715329.png

 

3、I have a few things to add about ISS66WVO32M8DBLL

Lin_Yishan_10-1722994715323.png

 

1.DQSM operates as a data mask when data is written to memory;

2.DQSM acts as the data synchronization clock when data/registers are read;

Lin_Yishan_11-1722994715259.png

 

1.Default value: 1111 0000 0010 0010 :0xf022

2.CR[3] Initial Access Latency: When used in conjunction with Latency counter, the multiple of Latency counter is determined. When this bit is 0, the multiple is determined according to whether there is Refresh Collision (Refresh collision means that a read or write operation is performed at the same time during a refresh operation, which may result in performance issues or data errors). Decide that if there is a refresh conflict, it will be twice, and if there is no refresh conflict, it will be 1 times. When this bit is 1, it is fixed to double.

4、The third step, call the above function, the address and data passed in, but the actual print results, read the data is wrong:

Lin_Yishan_12-1722994715324.png

 

Lin_Yishan_13-1722994715315.png

 

The above code is to write 32 bytes of data to memory, read it into the array, and print it out through the serial tool.

The results are as follows:

Without changing the memory type (originally AP Memory), the register reads correctly but the memory reads and writes incorrectly,

Lin_Yishan_14-1722994715325.png

 

Lin_Yishan_15-1722994714691.png

 

and after changing to Macronix RAM, the register reads and writes incorrectly:

Lin_Yishan_16-1722994715326.png

 

Lin_Yishan_17-1722994715327.png

 

I think there may be an error in the register configuration, hope you can answer the doubts, thank you very much!

I provide my code and peripheral information here.

3 REPLIES 3
QLiu.6
Associate II

Here is my code for  "APS6404L-3SQR-SN" in H723. Remember to config your MPU correctly.

QLiu6_0-1723000330450.png

 

QLiu6_1-1723000438913.png

QLiu6_2-1723000459058.png

 

 

#include "PsRam.h"
#include "main.h"
#include "octospi.h"

#define PS_OSPI hospi2
#define PSRAM_BASE (OCTOSPI2_BASE)
#define PSRAM_SIZE (8 * 1024 * 1024)
#define PSRAM_END (PSRAM_BASE + PSRAM_SIZE)

#define FAST_READ_QUAD 0xEB
#define QUAD_WRITE 0x38
#define FAST_READ_QUAD_DUMMY_CYCLES 6
#define WRITE_QUAD_DUMMY_CYCLES 0
#define ENTER_QUAD_DUMMY_CYCLES 0
#define ENTER_QUAD_MODE 0x35
#define EXIT_QUAD_MODE 0xF5

void PsInit()
{
	EnterQuadMode();
	EnableMemMappedQuadMode();
}

void EnableMemMappedQuadMode(void)
{
	OSPI_RegularCmdTypeDef sCommand;
	OSPI_MemoryMappedTypeDef sMemMappedCfg;
	sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
	sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_4_LINES;
	sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES;
	sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
	sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
	sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
	sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
	sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
	sCommand.Address = 0;
	sCommand.NbData = 1;
	/* Memory-mapped mode configuration for Quad Read mode 4-4-4*/
	sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
	sCommand.Instruction = FAST_READ_QUAD;
	sCommand.DummyCycles = FAST_READ_QUAD_DUMMY_CYCLES;
	if (HAL_OSPI_Command(&PS_OSPI, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		Throw("EnableMemMappedQuadMode()");
	}
	/* Memory-mapped mode configuration for Quad Write mode 4-4-4*/
	sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;
	sCommand.Instruction = QUAD_WRITE;
	sCommand.DummyCycles = WRITE_QUAD_DUMMY_CYCLES;
	sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
	if (HAL_OSPI_Command(&PS_OSPI, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		Throw("EnableMemMappedQuadMode()");
	}
	/*Disable timeout counter for memory mapped mode*/
	sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
	/*Enable memory mapped mode*/
	if (HAL_OSPI_MemoryMapped(&PS_OSPI, &sMemMappedCfg) != HAL_OK)
	{
		Throw("EnableMemMappedQuadMode()");
	}
}

void EnterQuadMode(void)
{
	OSPI_RegularCmdTypeDef sCommand;
	sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
	sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
	sCommand.Instruction = ENTER_QUAD_MODE;
	sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
	sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
	sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode = HAL_OSPI_DATA_NONE;
	sCommand.DummyCycles = ENTER_QUAD_DUMMY_CYCLES;
	sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
	sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
	/*Enter QUAD mode*/
	if (HAL_OSPI_Command(&PS_OSPI, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		Throw("EnterQuadMode()");
	}
}

int PsRamTest(unsigned char x)
{
#define TEST_XNUMBER 0x01000000
	typedef uint32_t psram_t;
	const int len = PSRAM_SIZE / sizeof(psram_t);
	const int steps = 32;
	__IO psram_t *mem_wr, *mem_rd;
	psram_t wr, rd;
	wr = rd = x * TEST_XNUMBER;
	mem_wr = mem_rd = (__IO psram_t *)PSRAM_BASE;
	int errcnt = 0;
	for (int i = 0; i < len / steps; i++)
	{
		for (int j = 0; j < steps; j++)
		{
			*mem_wr++ = wr++;
		}
		for (int j = 0; j < steps; j++)
		{
			if (*mem_rd++ != rd++)
			{
				errcnt++;
			}
		}
	}
	return errcnt;
}

 

Thank you for your reply. I have tried APS PSRAM, and I can read and write normally according to its official example, but ISSI's cannot run at present. And I did not use MPU in the application process, is ye to be enabled?

KDJEM.1
ST Employee

Hello @Lin_Yishan ,

 

Could you please refer to How to set up the OSPI peripheral to interface with the IS25LX256 from ISSI and get inspired to check your OCTOSPI configuration (Device type,  Delay hold quarter cycle ....).

AN5050 Table 8. STM32CubeMX - Configuration of OCTOSPI parameters explains how to configure the OCTOSPI parameters depending on the memory used.

I hope this help you.

Kaouthar

 

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.