2026-05-04 2:16 AM
Hello,
I am using STM32U5G-DK1 Discovery kit and need to store a large amount of data in on-board OSPI flash. Now, the example code by STM32 for this kit uses this OPSI flash in Memory-mapped mode. This mode is good to store an small amount of data but time-consuming when writing a large data to this Flash. Therefore, I need to use this Flash in Indirect mode where I can write to flash Page by Page. For this, I use the below configuration of OSPI:
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.Instruction = OCTAL_PAGE_PROG_CMD;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_16_BITS;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.Address = address;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.NbData = BUFFERSIZE; // :warning: max 256 bytes per page
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
if (HAL_OSPI_Transmit(&hospi1, aTxBuffer, HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
OSPI_AutoPollingMemReady(&hospi1);
But immediately after HAL_OSPI_Transmit ():, it stuck at Error_Handler(). Can you provide me code or tell me how can I write large chunks of data in this OSPI flash ?
With regard,
Sudarshan Chaudhary
2026-05-04 4:59 AM - edited 2026-05-04 5:01 AM
Hello @Sudarshan ,
Below is a code snippet that could help you and serve as inspiration: the memory must be configured in DDR OSPI mode.
#define OSPI_PAGE_SIZE 256
#define BufferSize 256
uint32_t max_size, size = 0;
uint32_t nb_sectors_to_erase;
uint32_t nb_page_to_program;
/******************************* Step 1: Erase memory ********************************************************************/
nb_sectors_to_erase = (max_size / OSPI_PAGE_SIZE) + 1;
for (uint16_t i=0; i < nb_sectors_to_erase; i++)
{
OSPI_WriteEnable(&hospi1);
/* Erasing Sequence -------------------------------------------------- */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.Instruction = 0x21DE;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionWidth = HAL_OSPI_INSTRUCTION_16_BITS;
sCommand.InstructionDTRMode = HAL_OSPI_INSTRUCTION_DTR_ENABLE;
sCommand.Address = i* OSPI_PAGE_SIZE;//WRITE_READ_ADDR;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressWidth = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDTRMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.AlternateBytes = 0;
sCommand.AlternateBytesMode = HAL_OSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = 0;
sCommand.AlternateBytesDTRMode = 0;
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.DataLength = 0;
sCommand.DataDTRMode = 0;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* Configure automatic polling mode to wait for end of erase ---------- */
OSPI_AutoPollingMemReady(&hospi1);
}
/**************************** Write in memory ************************************************************************/
nb_page_to_program = (max_size / OSPI_PAGE_SIZE) + 1;
for (uint16_t i=0; i < nb_page_to_program; i++)
{
if(i == (nb_page_to_program - 1))
{
size = max_size - i * OSPI_PAGE_SIZE;
}
else
{
size = OSPI_PAGE_SIZE;
}
/* Enable write operations ---------------------------------------- */
OSPI_WriteEnable(&hospi1);
/* Writing Sequence ------------------------------------------------ */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.Instruction = 0x12ED;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
sCommand.InstructionWidth = HAL_OSPI_INSTRUCTION_16_BITS;
sCommand.InstructionDTRMode = HAL_OSPI_INSTRUCTION_DTR_ENABLE;
sCommand.Address = i*OSPI_PAGE_SIZE;//WRITE_READ_ADDR;
sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
sCommand.AddressWidth = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDTRMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
sCommand.AlternateBytes = 0;
sCommand.AlternateBytesMode = HAL_OSPI_ALT_BYTES_NONE;
sCommand.AlternateBytesWidth = 0;
sCommand.AlternateBytesMode = 0;
sCommand.DataMode = HAL_OSPI_DATA_8_LINES;
sCommand.DataLength = size;//BufferSize;
sCommand.DataDTRMode = HAL_OSPI_DATA_DTR_ENABLE;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (HAL_OSPI_Transmit(&hospi1, flash_addr,HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
flash_addr += size;
OSPI_AutoPollingMemReady(&hospi1);
}