drivers: flash: stm32_qspi: Fix flash not reset when in QPI mode

The reset commands were sent only in SPI mode, causing the device not to
be properly reset when in QPI mode. On the STM32H747I-DISCO boards, this
was causing the driver initialization to fail due to a bad SFDP magic
after flashing the external memory using STM32CubeProgrammer since the
external loader is configuring the flash memory in QPI mode.

The commands are sent in QPI mode first, then in SPI mode:
- If the flash memory was in QPI mode, the two first reset commands are
  processed and after reset, the flash memory is in SPI mode and
  correctly handles the SPI mode reset commands.
- If the flash memory was in SPI mode, for each QPI command the chip
  select signal will be released before the flash memory had the
  opportunity to receive a whole command (1 byte), so the partially
  received commands will be ignored and won't cause any harm. Then, the
  chip is reset by the commands sent in SPI mode.

Signed-off-by: Thomas Altenbach <altenbach.thomas@gmail.com>
This commit is contained in:
Thomas Altenbach 2025-07-06 03:45:01 +02:00 committed by Daniel DeGrasse
parent 0081207078
commit 6aeb12d558

View File

@ -1402,10 +1402,29 @@ static int flash_stm32_qspi_send_reset(const struct device *dev)
{
QSPI_CommandTypeDef cmd = {
.Instruction = SPI_NOR_CMD_RESET_EN,
.InstructionMode = QSPI_INSTRUCTION_1_LINE,
.InstructionMode = QSPI_INSTRUCTION_4_LINES
};
int ret;
/*
* The device might be in SPI or QPI mode, so to ensure the device is properly reset send
* the reset commands in both QPI and SPI modes.
*/
ret = qspi_send_cmd(dev, &cmd);
if (ret != 0) {
LOG_ERR("%d: Failed to send RESET_EN", ret);
return ret;
}
cmd.Instruction = SPI_NOR_CMD_RESET_MEM;
ret = qspi_send_cmd(dev, &cmd);
if (ret != 0) {
LOG_ERR("%d: Failed to send RESET_MEM", ret);
return ret;
}
cmd.Instruction = SPI_NOR_CMD_RESET_EN;
cmd.InstructionMode = QSPI_INSTRUCTION_1_LINE;
ret = qspi_send_cmd(dev, &cmd);
if (ret != 0) {
LOG_ERR("%d: Failed to send RESET_EN", ret);