cancel
Showing results for 
Search instead for 
Did you mean: 

QSPI 32 bit addressing mode in STM32H753XI

AShel.1
Associate III

I'm using STM32H753XI Eval 2 board with MT25QL01GBBB external flash on QSPI interface.

I've configured it in 4 byte addressing mode but I'm not able to read the data correctly.

I've referred code from here,

https://github.com/STMicroelectronics/STM32CubeF7/blob/master/Projects/STM32F7308-DISCO/Examples/QSPI/QSPI_ReadWrite/Src/main.c

QSPI Init:

uint8_t QUADSPI_Init(void)
{
 
  hqspi.Instance = QUADSPI;
  hqspi.Init.ClockPrescaler = 1;
  hqspi.Init.FifoThreshold = 4;
  hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
  hqspi.Init.FlashSize = 31;//25;
  hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;//QSPI_CS_HIGH_TIME_1_CYCLE;
  hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
  hqspi.Init.FlashID = QSPI_FLASH_ID_1;
  hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
  if (HAL_QSPI_Init(&hqspi) != HAL_OK)
  {
    Error_Handler();
  }
/* QSPI memory reset */
	  if (QSPI_ResetMemory(&hqspi) != QSPI_OK)
	  {
	    return QSPI_NOT_SUPPORTED;
	  }
 
	  /* Put QSPI memory in QPI mode */
	  if( QSPI_EnterMemory_QPI( &hqspi )!=QSPI_OK )
	  {
	    return QSPI_NOT_SUPPORTED;
	  }
 
	  /* Set the QSPI memory in 4-bytes address mode */
	  if (QSPI_EnterFourBytesAddress(&hqspi) != QSPI_OK)
	  {
	    return QSPI_NOT_SUPPORTED;
	  }
 
	  /* Configuration of the dummy cycles on QSPI memory side */
	  if (QSPI_DummyCyclesCfg(&hqspi) != QSPI_OK)
	  {
	    return QSPI_NOT_SUPPORTED;
	  }
 
	  /* Configuration of the Output driver strength on memory side */
	  if( QSPI_OutDrvStrengthCfg( &hqspi ) != QSPI_OK )
	  {
	    return QSPI_NOT_SUPPORTED;
	  }
	  return QSPI_OK;
}

QSPI Read:

uint8_t QUADSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{
	 QSPI_CommandTypeDef s_command;
 
	  /* Initialize the read command */
	  s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
	  s_command.Instruction       = QPI_READ_4_BYTE_ADDR_CMD;
	  s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
	  s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
	  s_command.Address           = ReadAddr;
	  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
	  s_command.DataMode          = QSPI_DATA_4_LINES;
	  s_command.DummyCycles       = MX25L512_DUMMY_CYCLES_READ_QUAD_IO;
	  s_command.NbData            = Size;
	  s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
	  s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
	  s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
 
	  /* Configure the command */
	  if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	  {
	    return QSPI_ERROR;
	  }
	 // HAL_Delay( 10 );
	  /* Set S# timing for Read command */
	  MODIFY_REG(hqspi.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_3_CYCLE);
 
	  /* Reception of the data */
	  if (HAL_QSPI_Receive(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	  {
	    return QSPI_ERROR;
	  }
 
	  /* Restore S# timing for nonRead commands */
	  MODIFY_REG(hqspi.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_6_CYCLE);
	  HAL_Delay( 100 );
  return QSPI_OK;
}

Is there any issue in configuration or read function?

1 ACCEPTED SOLUTION

Accepted Solutions
Andreas Bolsch
Lead II

Hm, "not able to read the data correctly." means what? Just FFs, 00s, shifted data ...

Are you sure you know the actual contents of the flash so that you can decide whether the data read is correct or not? For programming, you need the 4-byte addressing as well?! Whether the flash had been successfully switched to 4-byte addressing can be checked via "Flag Status Register", bit 0. So, after QSPI_EnterFourBytesAddress, check this bit.

View solution in original post

6 REPLIES 6

Certainly not 31-bit wide at the window, 256 MB max

Not an MX25L512 nor F7

Probably pushing the wrong commands, Micron not Macronix part

Why not use the H7 BSP for the board, and Micron chip?

Mostly configured in Dual pairs, ie 1 Gbit via 2x 512 Mbit die

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

STM32Cube_FW_H7_V1.7.0\Projects\STM32H743I-EVAL\Examples\BSP\Src\qspi.c

STM32Cube_FW_H7_V1.7.0\Drivers\BSP\STM32H743I-EVAL\stm32h743i_eval_qspi.c

STM32Cube_FW_H7_V1.7.0\Drivers\BSP\Components\mt25tl01g\mt25tl01g.c

STM32Cube_FW_H7_V1.7.0\Drivers\BSP\Components\mt25tl01g\mt25tl01g.h

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

Thanks for your response.

I'm using Micron part with STM32H7XI and everything works fine in 24 bit addressing mode. to read the addresses > 24 bit I've changed the code for 4 byte addressing mode then nothing is working

my earlier configuration and code which works fine is

uint8_t QUADSPI_Init(void)
{
	  /* Initialize QuadSPI ------------------------------------------------------ */
	  QSPIHandle.Instance = QUADSPI;
	  HAL_QSPI_DeInit(&QSPIHandle);
 
	  QSPIHandle.Init.ClockPrescaler     = 1;
	  QSPIHandle.Init.FifoThreshold      = 4;
	  QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
	  QSPIHandle.Init.FlashSize          = 25;
	  QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
	  QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
	  QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
	  QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
 
	  if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
	  {
		  return QSPI_ERROR;
	  }
	  /* QSPI memory reset */
	  if (QSPI_ResetMemory(&QSPIHandle) != HAL_OK)
	   {
		  return QSPI_ERROR;
	   }
 
	   /* Configuration of the dummy cycles on QSPI memory side */
	  if (QSPI_DummyCyclesCfg(&QSPIHandle) != HAL_OK)
	   {
		  return QSPI_ERROR;
	   }
	  return QSPI_OK;
}
 
uint8_t QUADSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{
  QSPI_CommandTypeDef s_command;
 
 
  /* Initialize the read command */
  s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  s_command.Instruction       = QUAD_OUT_FAST_READ_CMD;//QUAD_INOUT_FAST_READ_CMD;
  s_command.AddressMode       = QSPI_ADDRESS_1_LINE;//QSPI_ADDRESS_4_LINES;//
  s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
  s_command.Address           = ReadAddr;
  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  s_command.DataMode          = QSPI_DATA_4_LINES;
  s_command.DummyCycles       = MT25QL128_DUMMY_CYCLES_READ_QUAD;
  s_command.NbData            = Size;
  s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
  s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
 
  /* Configure the command */
  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }
 
  /* Set S# timing for Read command */
  MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_3_CYCLE);
  /* Reception of the data */
#ifdef DMA_ENABLED
  RxCplt = 0;
  if (HAL_QSPI_Receive_DMA(&QSPIHandle, pData) != HAL_OK)
  {
    return QSPI_ERROR;
  }
  while(RxCplt == 0)
  {
 
  }
#else
  if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
      return QSPI_ERROR;
    }
#endif
  /* Restore S# timing for nonRead commands */
  MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_6_CYCLE);
 
  return QSPI_OK;
}

Andreas Bolsch
Lead II

Hm, "not able to read the data correctly." means what? Just FFs, 00s, shifted data ...

Are you sure you know the actual contents of the flash so that you can decide whether the data read is correct or not? For programming, you need the 4-byte addressing as well?! Whether the flash had been successfully switched to 4-byte addressing can be checked via "Flag Status Register", bit 0. So, after QSPI_EnterFourBytesAddress, check this bit.

I've initialized it into 4 byte addressing mode then sent erase sector command to erase sector 0 and read back sector 0 to check if it is erased successfully or not. but this time I can read data as 0xE7 instead 0xFF. It is not giving eny HAL error, time out for transmission/ reception of any command, data. does 4 byte addressing mode needs more CS_HIGH_TIME ctcles?

MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_3_CYCLE);

This doesn't help: As you didn't check whether 4-byte mode had indeed been activated, you can't know whether the sector erase did work as expected, so you can't tell whether the read works properly either.

I'd suggest you program the first 16 MBytes with a known pattern (e.g. random data) in 3-byte mode, do a verify and then switch to 4-byte mode. Then check Flag Status Register. If it indicates 4-byte mode had indeed been activated you can proceed with testing read access.