2022-07-21 06:56 AM
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
2022-07-22 06:27 AM
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.