Skip to main content
Visitor II
November 16, 2021
Solved

NOR memory stop working after changing nonvolatile configuration register

  • November 16, 2021
  • 2 replies
  • 1641 views

Hello,

Im using STM32H745 on custom board, with Micron Flash Memory (MT25QU512ABB)

Board is tested, I was able to manage NOR memory through QSPI.

I tried to change nonvolatile configuration register to set two things:

  • Number of address bytes during command entry to 4-byte address mode
  • Enable Quad I/O protocol

This is code I used:

uint8_t QSPI_Set_Nonvolatile_Reg_Config(void) {
 
	QSPI_CommandTypeDef sCommand;
	uint8_t test_buffer[4] = { 0 };
 
	/*read configuration register*/
	sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
	sCommand.Instruction = 0xB5; //READ NONVOLATILE CONFIGURATION REGISTER
	sCommand.AddressMode = QSPI_ADDRESS_NONE;
	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode = QSPI_DATA_1_LINE;
	sCommand.DummyCycles = 0;
	sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
	sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
	sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
	sCommand.NbData = 2;
 
	if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		return HAL_ERROR;
	}
	if (HAL_QSPI_Receive(&hqspi, test_buffer, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
		return HAL_ERROR;
	}
 
	sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
	sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
	sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
	sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
	sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
	sCommand.Instruction = 0xB1; //WRITE NONVOLATILE CONFIGURATION REGISTER
	sCommand.AddressMode = QSPI_ADDRESS_NONE;
	sCommand.DataMode = QSPI_DATA_1_LINE;
	sCommand.DummyCycles = 0;
	sCommand.NbData = 2;
 
	//modify buffer to enable quad mode
	//0b1111 1111 1111 0110
 //MODIFY_REG(test_buffer[1], 0x9, 0x0);
	test_buffer[0] = 0xFF;
	test_buffer[1] = 0xF6;
 
 // On the first try, i didnt use QSPI__WriteEnable(), that maybe my main error
 // if (QSPI_WriteEnable() != HAL_OK) {
 // 	return HAL_ERROR;
 // }
 
	if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
			!= HAL_OK) {
		return HAL_ERROR;
	}
 
	if (HAL_QSPI_Transmit(&hqspi, test_buffer, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
		Error_Handler();
		return HAL_ERROR;
	}
 
	/*read configuration register*/
	sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
	sCommand.Instruction = 0xB5; //READ NONVOLATILE CONFIGURATION REGISTER
	sCommand.AddressMode = QSPI_ADDRESS_NONE;
	sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode = QSPI_DATA_1_LINE;
	sCommand.DummyCycles = 0;
	sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
	sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
	sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
	sCommand.NbData = 2;
 
	if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
		return HAL_ERROR;
	}
	if (HAL_QSPI_Receive(&hqspi, test_buffer, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
		return HAL_ERROR;
	}
 
	return HAL_OK;
}

First time I used it, i didn't use QSPI_WriteEnable command.

Yet, after I run QSPI_Set_Nonvolatile_Reg_Config(), everything stopped working.

In this code, AutoPolling started returning error, because of timeout (it didnt get StatusMatch flag), so my code doesnt go any futher.

Diffrent code I run on this board, where I had this memory working as intended, it also stopped working after change to this register, and reading memory gives somewhat random values(i didnt find any meaning in this mess). Erase and Write also no longer works.

The thing is, when I use QSPI_Set_Nonvolatile_Reg_Config() just to read this register, its 0xFFFF, like I didnt change anything (i need it set to 0xFFF6).

Tried to change this register many times, later adding WriteEnable command, but to no avail. It always reads 0xFFFF, even right after supposed change.

So, it looks like nothing is changed, yet nothing works anymore.

Is there some way to reset memory to its fabric settings, or maybe I permamently damage it?

I will be grateful for any kind of help,

Andrew

    This topic has been closed for replies.
    Best answer by Andreas Bolsch

    It seems you've used wrong byte order: "The WRITE NONVOLATILE CONFIGURATION REGISTER operation must have input data

    starting from the least significant byte.". So, your test_buffer[0] went to bits 0 to 7, and test_buffer[1] to bits 8 to 15. This means

    "XIP: Quad output fast read" is active at power up. See the chapter about "XIP Mode" in datasheet to get out of XIP mode, afterwards you can reprogram the configuration register.

    2 replies

    Explorer II
    November 16, 2021

    It seems you've used wrong byte order: "The WRITE NONVOLATILE CONFIGURATION REGISTER operation must have input data

    starting from the least significant byte.". So, your test_buffer[0] went to bits 0 to 7, and test_buffer[1] to bits 8 to 15. This means

    "XIP: Quad output fast read" is active at power up. See the chapter about "XIP Mode" in datasheet to get out of XIP mode, afterwards you can reprogram the configuration register.

    AWęgl.1Author
    Visitor II
    November 17, 2021

    Thank you for your answer, as you suggest, I looked into exiting XIP mode and found out that I do so "by driving the XIP confirmation

    bit to 1."

    "This bit is the value on DQ0 during the first dummy clock cycle in the FAST READ operation."

    0693W00000GXx0jQAD.png 

    I don't really understand, how can I set this bit in dummy cycles. On the contrary, there is a point made, that there can't be anything during dummy clocks cycles.

    From RM0399:

    0693W00000GXx4CQAT.pngDid I misunderstood something? Is there any way to set this confirmation bit on STM32H745?

    Explorer II
    November 18, 2021

    That's what the "Alternate Byte(s)" phase could be used for. Of course, the number of dummy cycles in DCYC field has to be reduced accordingly.

    For the flash, the dummy phase is rather irrelevant, the QSPI could simply continue to send dummy data or receive and discard dummy data, except that there must be some "bus free" time for turnaround

    AWęgl.1Author
    Visitor II
    November 18, 2021

    Thank you very much, it worked as you suggested. After setting confirmation bit, I was able to change nonvolatile configuration register, restoring default settings. Memory work as intended.

    You were most helpful, thanks.