what is the sequence to work S25FL512 in QSPI mode

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
yogeshnandurkar
Level 1
Level 1
5 sign-ins First reply posted First question asked

hi, 

I am working on S25Fl512, The default mode is SPI and dual mode, which is working properly.

but in case i want to use QSPI mode, I could not do this. I think my sequence is wrong, I am posting the function to enter in QSPI mode, please correct me where i am wrong.

 

 

 

 

 

 

 

 

int32_t QSPI_EnterQPIMode(QSPI_HandleTypeDef *hqspi)
{
  QSPI_CommandTypeDef s_command;
  uint8_t data[] = {0x02, 0x02};
  s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  s_command.Instruction       = 0x01;//MT25TL01G_ENTER_QUAD_CMD;
  s_command.AddressMode       = QSPI_ADDRESS_NONE;
  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  s_command.DataMode          = QSPI_DATA_NONE;
  s_command.DummyCycles       = 0;
  s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
  s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;


  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  {
	  return QSPI_ERROR;
  }

  /* Configure the command */
  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
	  return QSPI_ERROR;
  }

  /* Transmission of the data */
  if (HAL_QSPI_Transmit(&QSPIHandle, data, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
	  return QSPI_ERROR;
  }

  /* Configure automatic polling mode to wait for end of program */
  if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
  {
	  return QSPI_ERROR;
  }
  return QSPI_OK;
}
uint8_t BSP_QSPI_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       = 0x6B;//QUAD_OUT_FAST_READ_CMD; /* same value on both memory types */  // for single line 0x03; dual line 0x3B
  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       = 0x08;//QspiInfo.DummyCyclesRead;                                     //for single line 0x00;
  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: Min 20ns for N25Q512A memory and 10ns for S25FL512S memory */
  MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_2_CYCLE);

  /* Reception of the data */
  if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return QSPI_ERROR;
  }

  /* Restore S# timing for nonRead commands */
  MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_5_CYCLE);

  return QSPI_OK;
}

/**
  * @brief  Writes an amount of data to the QSPI memory.
  * @param  pData: Pointer to data to be written
  * @param  WriteAddr: Write start address
  * @param  Size: Size of data to write
  * @retval QSPI memory status
  */
uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
{
  QSPI_EnterQPIMode(&QSPIHandle);
  QSPI_CommandTypeDef s_command;
  uint32_t end_addr, current_size, current_addr;

  /* Calculation of the size between the write address and the end of the page */
  current_size = QspiInfo.ProgPageSize - (WriteAddr % (QspiInfo.ProgPageSize));

  /* Check if the size of the data is less than the remaining place in the page */
  if (current_size > Size)
  {
    current_size = Size;
  }

  /* Initialize the adress variables */
  current_addr = WriteAddr;
  end_addr = WriteAddr + Size;

  /* Initialize the program command */
  s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  s_command.Instruction       = 0x32;//QUAD_IN_FAST_PROG_CMD; /* same value on both memory types */  // single line command 0x02
  s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
  s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  s_command.DataMode          = QSPI_DATA_4_LINES;
  s_command.DummyCycles       = 0;
  s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
  s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;

  /* Perform the write page by page */
  do
  {
    s_command.Address = current_addr;
    s_command.NbData  = current_size;

    /* Enable write operations */
    if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
    {
      return QSPI_ERROR;
    }

    /* Configure the command */
    if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
      return QSPI_ERROR;
    }

    /* Transmission of the data */
    if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
      return QSPI_ERROR;
    }

    /* Configure automatic polling mode to wait for end of program */
    if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
    {
      return QSPI_ERROR;
    }

    /* Update the address and size variables for next page programming */
    current_addr += current_size;
    pData += current_size;
    current_size = ((current_addr + QspiInfo.ProgPageSize) > end_addr) ? (end_addr - current_addr) : QspiInfo.ProgPageSize;
  } while (current_addr < end_addr);

  return QSPI_OK;
}

 

 

 

 

 

 

 

 

 controller is STM32H743,

please suggest me sequence, or else if any example let me konw.

thanking you

0 Likes
1 Solution

Hello Yogesh,

I did not notice the WREN (command 06h) being sent to the flash, prior to the WRR (command 01h).

The Write Enable (WREN) command must be written prior to any command that modifies nonvolatile data.  Therefore, a Write Enable (WREN) command must be received before the Write Registers (WRR) command can be accepted by the device.  The WEL bit must be set to 1 to enable program, write, or erase operations as a means to provide protection against inadvertent changes to memory or register values.  The Write Enable (WREN) command execution sets the Write Enable Latch to a 1 to allow any program, erase, or write commands to execute afterwards.

Hope this helps...

 

Best regards,

Albert

Cypress Semiconductor Corp.

An Infineon Technologies Company

View solution in original post

0 Likes
5 Replies
lock attach
Attachments are accessible only for community members.
AlbertB_56
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 replies posted

Hello Yogesh,

Thank you for contacting Infineon Technologies.

The S25FL512S has a configuration register (CR1), and the default setting at power up is serial/dual mode.   The configuration register bit that is required to change from Serial/Dual mode to Quad mode, is bit-1 (CR1[1]).  Please ensure to change CR1[1] from '0' to '1'.  When CR1[1] = '1' the S25FL512S will be configured on quad mode. 

 

Please find attached the datasheet for the S25FL512S, and refer to page 49, Section 7.6.2, Table 19 for the Configuration Register-1 (CR1) default settings.

 

Best regards,

Albert

Cypress Semiconductor Corp.

An Infineon Technologies Company

 

0 Likes

Thank you reply,

The above enterQPI function sequence is Correct? 

The first I have to send 01 then status register data and after that confg reg data, before that I have send write enable command . Once you have done this read cr1 reg 

If I am wrong correct me.

Can you send me qspi mode enable function sequence. Because I have tried it many time .

Thanking you

0 Likes

Hello Yogesh,

I did not notice the WREN (command 06h) being sent to the flash, prior to the WRR (command 01h).

The Write Enable (WREN) command must be written prior to any command that modifies nonvolatile data.  Therefore, a Write Enable (WREN) command must be received before the Write Registers (WRR) command can be accepted by the device.  The WEL bit must be set to 1 to enable program, write, or erase operations as a means to provide protection against inadvertent changes to memory or register values.  The Write Enable (WREN) command execution sets the Write Enable Latch to a 1 to allow any program, erase, or write commands to execute afterwards.

Hope this helps...

 

Best regards,

Albert

Cypress Semiconductor Corp.

An Infineon Technologies Company

0 Likes
AlbertB_56
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 replies posted

Hello Yogesh,

I did not notice the WREN (command 06h) being sent to the flash, prior to the WRR (command 01h).

The Write Enable (WREN) command must be written prior to any command that modifies nonvolatile data.  Therefore, a Write Enable (WREN) command must be received before the Write Registers (WRR) command can be accepted by the device.  The WEL bit must be set to 1 to enable program, write, or erase operations as a means to provide protection against inadvertent changes to memory or register values.  The Write Enable (WREN) command execution sets the Write Enable Latch to a 1 to allow any program, erase, or write commands to execute afterwards.

Hope this helps...

 

Best regards,

Albert

Cypress Semiconductor Corp.

An Infineon Technologies Company

0 Likes

hi  ,

It is given in the function, above in first comment.

int32_t QSPI_EnterQPIMode(QSPI_HandleTypeDef *hqspi)

regards,

yogesh

0 Likes