cancel
Showing results for 
Search instead for 
Did you mean: 

QSPI reading and Writing function not showing correct data

ykn
Senior

hi,

I am trying to implement QSPI in STM32H743 with S25FL512.

REad ID function work properly, showing correct data like command

0x9F

result: {01}{02}{20}{4D}{00}{80}

memory size 65Mbyte

but the BSP_QSPI_READ/WRITE function not correct data,

 some one guide me.

thanking you

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       = QUAD_OUT_FAST_READ_CMD; /* same value on both memory types */
  s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
  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       = QspiInfo.DummyCyclesRead;
  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_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       = QUAD_IN_FAST_PROG_CMD; /* same value on both memory types */
  s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
  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;
}
 
  * @brief  S25FL512S Configuration
  */
#define S25FL512S_FLASH_SIZE                            0x4000000 /* 512 MBits => 64MBytes */
#define S25FL512S_SECTOR_SIZE                           0x40000   /* 256 sectors of 256KBytes */
#define S25FL512S_PAGE_SIZE                             0x200     /* 131072 pages of 512 bytes */
 
#define S25FL512S_BULK_ERASE_MAX_TIME                   460000
#define S25FL512S_SECTOR_ERASE_MAX_TIME                 2600
 
 
/**
  * @brief  S25FL512S Commands
  */
/* Reset Operations */
#define S25FL512S_SOFTWARE_RESET_CMD                    0xF0
#define S25FL512S_MODE_BIT_RESET_CMD                    0xFF
 
/* Identification Operations */
#define S25FL512S_READ_ID_CMD                           0x90
#define S25FL512S_READ_ID_CMD2                          0x9F
#define S25FL512S_READ_ELECTRONIC_SIGNATURE             0xAB
#define S25FL512S_READ_SERIAL_FLASH_DISCO_PARAM_CMD     0x5A
 
/* Register Operations */
#define S25FL512S_READ_STATUS_REG1_CMD                  0x05
#define S25FL512S_READ_STATUS_REG2_CMD                  0x07
#define S25FL512S_READ_CONFIGURATION_REG1_CMD           0x35
#define S25FL512S_WRITE_STATUS_CMD_REG_CMD              0x01
#define S25FL512S_WRITE_DISABLE_CMD                     0x04
#define S25FL512S_WRITE_ENABLE_CMD                      0x06
#define S25FL512S_CLEAR_STATUS_REG1_CMD                 0x30
#define S25FL512S_READ_AUTOBOOT_REG_CMD                 0x14
#define S25FL512S_WRITE_AUTOBOOT_REG_CMD                0x15
#define S25FL512S_READ_BANK_REG_CMD                     0x16
#define S25FL512S_WRITE_BANK_REG_CMD                    0x17
#define S25FL512S_ACCESS_BANK_REG_CMD                   0xB9
#define S25FL512S_READ_DATA_LEARNING_PATTERN_CMD        0x41
#define S25FL512S_PGM_NV_DATA_LEARNING_REG_CMD          0x43
#define S25FL512S_WRITE_VOL_DATA_LEARNING_REG_CMD       0x4A
 
/* Read Operations */
#define S25FL512S_READ_CMD                              0x03
#define S25FL512S_READ_4_BYTE_ADDR_CMD                  0x13
 
#define S25FL512S_FAST_READ_CMD                         0x0B
#define S25FL512S_FAST_READ_4_BYTE_ADDR_CMD             0x0C
#define S25FL512S_FAST_READ_DDR_CMD                     0x0D
#define S25FL512S_FAST_READ__DDR_4_BYTE_ADDR_CMD        0x0E
 
#define S25FL512S_DUAL_OUT_FAST_READ_CMD                0x3B
#define S25FL512S_DUAL_OUT_FAST_READ_4_BYTE_ADDR_CMD    0x3C
 
#define S25FL512S_QUAD_OUT_FAST_READ_CMD                0x6B
#define S25FL512S_QUAD_OUT_FAST_READ_4_BYTE_ADDR_CMD    0x6C
 
#define S25FL512S_DUAL_INOUT_FAST_READ_CMD              0xBB
#define S25FL512S_DUAL_INOUT_FAST_READ_DTR_CMD          0xBD
#define S25FL512S_DUAL_INOUT_FAST_READ_4_BYTE_ADDR_CMD  0xBC
#define S25FL512S_DDR_DUAL_INOUT_READ_4_BYTE_ADDR_CMD   0xBE
 
#define S25FL512S_QUAD_INOUT_FAST_READ_CMD              0xEB
#define S25FL512S_QUAD_INOUT_FAST_READ_4_BYTE_ADDR_CMD  0xEC
#define S25FL512S_QUAD_INOUT_FAST_READ_DDR_CMD          0xED
#define S25FL512S_QUAD_INOUT_READ_DDR_4_BYTE_ADDR_CMD   0xEE
 
 
/* Program Operations */
#define S25FL512S_PAGE_PROG_CMD                         0x02
#define S25FL512S_PAGE_PROG_4_BYTE_ADDR_CMD             0x12
 
#define S25FL512S_QUAD_IN_FAST_PROG_CMD                 0x32
#define S25FL512S_QUAD_IN_FAST_PROG_ALTERNATE_CMD       0x38
#define S25FL512S_QUAD_IN_FAST_PROG_4_BYTE_ADDR_CMD     0x34
 
#define S25FL512S_PROGRAM_SUSPEND_CMD                   0x85
#define S25FL512S_PROGRAM_RESUME_CMD                    0x8A
 
/* Erase Operations */
#define S25FL512S_SECTOR_ERASE_CMD                      0xD8
#define S25FL512S_SECTOR_ERASE_4_BYTE_ADDR_CMD          0xDC
 
#define S25FL512S_BULK_ERASE_CMD                        0x60
#define S25FL512S_BULK_ERASE_ALTERNATE_CMD              0xC7
 
#define S25FL512S_PROG_ERASE_SUSPEND_CMD                0x75
#define S25FL512S_PROG_ERASE_RESUME_CMD                 0x7A
 
/* One-Time Programmable Operations */
#define S25FL512S_PROG_OTP_ARRAY_CMD                    0x42
#define S25FL512S_READ_OTP_ARRAY_CMD                    0x4B
 
/* Advanced Sector Protection Operations */
#define S25FL512S_READ_DYB_CMD                          0xE0
#define S25FL512S_WRITE_DYB_CMD                         0xE1
 
#define S25FL512S_READ_PPB_CMD                          0xE2
#define S25FL512S_PROGRAM_PPB_CMD                       0xE3
#define S25FL512S_ERASE_PPB_CMD                         0xE4
 
#define S25FL512S_READ_ASP_CMD                          0x2B
#define S25FL512S_PROGRAM_ASP_CMD                       0x2F
 
#define S25FL512S_READ_PPB_LOCKBIT_CMD                  0xA7
#define S25FL512S_WRITE_PPB_LOCKBIT_CMD                 0xA6
 
#define S25FL512S_READ_PASSWORD_CMD                     0xE7
#define S25FL512S_PROGRAM_PASSWORD_CMD                  0xE8
#define S25FL512S_UNLOCK_PASSWORD_CMD                   0xE9

1 REPLY 1
ykn
Senior

now, I switched to 1 - 1 - 1 mode to test the code, and surprisingly it worked with this mode.

what could be the problem that, it is not working with 1 - 1 - 4 mode.

thanking you.