cancel
Showing results for 
Search instead for 
Did you mean: 

OCTOSPI with STM32H573 and ISSI external flash IS25LX064. Setting Dummy cycles does not work

aco990
Associate III

Hi everyone,
I use the IS25LX064 OctoSPI Flash memory with the STM32H573 and after configuring the OctoSPI flash i can read the device Id of the flash successfully. But when i change the configuration of the Volatile configuration register by setting the dummy cycles (see function OSPI_DummyCycles in the code below) there is no change in the register. When i read the register after setting the dummy cycle i get 0xFF and so the change has no effect.

Does anyone know what could be the problem did i omit something in the configuration?
The gpio config is fine because i can read the device id . Also if i try to write to a reserved address of the volatile configuration register and then read the flag status register, i see that the error bit in the status register is set which is exepected. But writing to the dummy cycle address of the volatile config register has no effect and no error is reported in flag status register.

@AME MCU Support Center BB, @Tesla DeLorean, @Amel NASRI, @MNapi do you have any idea?

Datasheet of the controller
https://www.issi.com/WW/pdf/25LX-WX032-064.pdf

I use the following code to set the dummy cycles

 

 

 

static void MX_OCTOSPI1_Init(void) {

	/* USER CODE BEGIN OCTOSPI1_Init 0 */

	/* USER CODE END OCTOSPI1_Init 0 */

	/* USER CODE BEGIN OCTOSPI1_Init 1 */

	/* USER CODE END OCTOSPI1_Init 1 */
	/* OCTOSPI1 parameter configuration*/
	hospi1.Instance = OCTOSPI1;
	hospi1.Init.FifoThresholdByte = 1;
	hospi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
	hospi1.Init.MemoryType = HAL_XSPI_MEMTYPE_MICRON;
	hospi1.Init.MemorySize = HAL_XSPI_SIZE_8MB;
	hospi1.Init.ChipSelectHighTimeCycle = 2;
	hospi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
	hospi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
	hospi1.Init.WrapSize = HAL_XSPI_WRAP_NOT_SUPPORTED;
	hospi1.Init.ClockPrescaler = 3;
	hospi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;
	hospi1.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_ENABLE;
	hospi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE;
	hospi1.Init.DelayBlockBypass = HAL_XSPI_DELAY_BLOCK_BYPASS;
	hospi1.Init.Refresh = 0;
	if (HAL_XSPI_Init(&hospi1) != HAL_OK) {
		Error_Handler();
	}
	/* USER CODE BEGIN OCTOSPI1_Init 2 */

	/* USER CODE END OCTOSPI1_Init 2 */

}


static void ReadId(XSPI_HandleTypeDef *hospi) {
	XSPI_RegularCmdTypeDef sCommand = { 0 };

	uint8_t deviceId[20];

	sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
	sCommand.Instruction = 0x9E; /*----- read device id command ------*/
	sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
	sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
	sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
	sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
	sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
	sCommand.DataLength = 20;
	sCommand.DummyCycles = 0;
	sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
	sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

	if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	if (HAL_XSPI_Receive(hospi, deviceId, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}
}

static void WriteEnable(XSPI_HandleTypeDef *hospi) {
	XSPI_RegularCmdTypeDef sCommand = { 0 };
	XSPI_AutoPollingTypeDef sConfig = { 0 };

	/* Enable write operations ------------------------------------------ */
	sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
	sCommand.Instruction = 0x06; /*----- write enable command ---*/
	sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
	sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
	sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
	sCommand.DataMode = HAL_XSPI_DATA_NONE;
	sCommand.DummyCycles = 0;
	sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
	sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

	if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	/* Configure automatic polling mode to wait for write enabling ---- */
	sCommand.Instruction = 0x05; /*---- read status register command ----*/
	sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
	sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
	sCommand.DataLength = 1;

	if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	sConfig.MatchValue = 0x02; /*------- write enable value ---*/
	sConfig.MatchMask = 0x02; /*--------write enable match-----*/
	sConfig.MatchMode = HAL_XSPI_MATCH_MODE_AND;
	sConfig.IntervalTime = AUTO_POLLING_INTERVAL;
	sConfig.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE;

	if (HAL_XSPI_AutoPolling(hospi, &sConfig, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}
}

static void OSPI_DummyCycles(XSPI_HandleTypeDef *hospi) {

	XSPI_RegularCmdTypeDef sCommand = { 0 };
	XSPI_AutoPollingTypeDef sConfig = { 0 };
	uint8_t reg;

	/* Enable write operations ---------------------------------------- */
	WriteEnable(hospi);

	sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
	sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
	sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.Instruction = 0x81; /*----- write volatile config register command---*/
	sCommand.Address = 0x00000001;
	sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
	sCommand.AddressWidth = HAL_XSPI_ADDRESS_32_BITS;
	sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
	sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
	sCommand.DummyCycles = 0;
	sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
	sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;
	sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
	sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
	sCommand.DataLength = 1;

	if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	reg = 0x06;

	if (HAL_XSPI_Transmit(hospi, &reg, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	/* Wait that the memory is ready ---------------------------------- */
	sCommand.Instruction = 0x05; /*------- read status register command-------*/
	sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;

	if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	sConfig.MatchValue = 0x00;
	sConfig.MatchMask = 0x01;
	sConfig.MatchMode = HAL_XSPI_MATCH_MODE_AND;
	sConfig.IntervalTime = AUTO_POLLING_INTERVAL;
	sConfig.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE;

	if (HAL_XSPI_AutoPolling(hospi, &sConfig, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	/* ensure dummy cycle is set correctly */

	sCommand.Instruction = 0x85; /*---- read volatile configuration register cmd----*/
	sCommand.Address = 0x00000001;
	sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;

	if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}

	uint8_t dummyCycles = 0;

	if (HAL_XSPI_Receive(hospi, &dummyCycles, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		Error_Handler();
	}
}

 

 

 

 

 



1 ACCEPTED SOLUTION

Accepted Solutions

I fixed the title to match the body.

 

64 Mbit / 8 MB is likely not in 32-bit addressing mode, would likely want to fix that. I'd suggest dumping the non-volatile content prior to changing.

Also do the dummy cycles need changing?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

5 REPLIES 5
KDJEM.1
ST Employee

Hello @aco990 ,

Please make sure that when reading volatile register 0x85h the dummy cycles are "8" not "0" referring to the memory datasheet table 8.1. 

KDJEM1_1-1723467319234.png

Could you please check the memory size. According the memory datasheet the the IS25LX032 memory size is 32Mbits.

The last version of STM32CubeMX 6.12 for windows uses the Bits unity for memory size. So, the memory size must be configure to 32MBits in STM32CubeMX. Please take a look at this post to check the memory size. 

KDJEM1_0-1723466708318.png

Thank 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.

Hi Kaouthar,
the memory size is correct, it's 8MBytes. I am using the IS25LX064 Flash which has 64Mbits (8Mbytes).

aco990_0-1723469237124.png

I set the dummy cycles to 8 for reading the volatile config register but still the same error.

Thank you!

Hi @aco990 ,

-->OCTOSPI with STM32H573 and ISSI external flash IS25LX032. Setting Dummy cycles does not work

-->I use the IS25LX064 OctoSPI Flash memory with the STM32H573

Thank you for this clarification about the memory reference

Could you please use the latest version of STM32CubeMX 6.12.0 because there is a bug with the older version of  STM32CubeMx and STM32CubeIDE toolchain as mentioned here.

Could you please check the DEVSIZE field of OCTOSPI_DCR1.

Thank 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.

I fixed the title to match the body.

 

64 Mbit / 8 MB is likely not in 32-bit addressing mode, would likely want to fix that. I'd suggest dumping the non-volatile content prior to changing.

Also do the dummy cycles need changing?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hmm, thanks @Tesla DeLorean , now i can read 0x1F which is the default value of the dummy cycle and after setting the new value the register value is set to the new one. The Problem was the the address width. With HAL_XSPI_ADDRESS_24_BITS it works fine.