2024-12-03 07:33 AM
Hi.
I'm using a STM32U5A5 MCU to communicate with a FLASH device through OCTOSPI.
Flash is connected to port P1, and all signals are controlled by OCTOSPIM / OCTOSPI1 MCU hardware.
I'm sending command "0x06" = WRITE_ENABLE, and after that I need to check that bit "WEL" (Write Enable Latch) is set in STATUS register. Nothing exotic here, just regular FLASH operations.
Reading device status register is performed by sending command "0x0F" = GET_FEATURES with 8-bit address 0xC0 = "STATUS". Device will ouput STATUS value on the next 8 clocks.
What I see is that function HAL_OSPI_AutoPolling() seems to be reading 1 extra byte :
The first 06 command is my WRITE_ENABLE command on 8 clocks.
The next 0F C0 command is isssued by polling. Note the 2 bytes "02 02" in output. Polling stops immediately because condition is met. Total is 32 clocks, while it should be 24 clocks only.
If I don't use HAL_OSPI_AutoPolling() but HAL_OSPI_Receive() to manually read once the STATUS register, I have the expected signals :
First command is "06" = WRITE_ENABLE on 8 clocks.
Next command is "0F C0" = GET_FEATURES(STATUS) and status value = "02" as output. Total is 24 clocks as expected.
Code :
void octospi_flash_set_WEL(enum octospi_t octospi)
{
OSPI_RegularCmdTypeDef scmd;
scmd.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
scmd.FlashId = HAL_OSPI_FLASH_ID_1;
scmd.Instruction = 0x06U/*WRITE_ENABLE*/;
scmd.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
scmd.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
scmd.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
//scmd.Address = 0x00U;
scmd.AddressMode = HAL_OSPI_ADDRESS_NONE;
//scmd.AddressSize = HAL_OSPI_ADDRESS_8_BITS;
//scmd.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
//scmd.AlternateBytes = 0xFFFFFFFFU;
scmd.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
//scmd.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS;
//scmd.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
scmd.DataMode = HAL_OSPI_DATA_NONE;
//scmd.NbData = 0U;
//scmd.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
scmd.DummyCycles = 0U;
scmd.DQSMode = HAL_OSPI_DQS_DISABLE;
scmd.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
HAL_OSPI_Command(&ctxt[octospi].handle, &scmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
scmd.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
scmd.FlashId = HAL_OSPI_FLASH_ID_1;
scmd.Instruction = 0x0FU/*GET_FEATURES*/;
scmd.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
scmd.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
scmd.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
scmd.Address = 0xC0U/*STATUS*/;
scmd.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
scmd.AddressSize = HAL_OSPI_ADDRESS_8_BITS;
scmd.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
//scmd.AlternateBytes = 0xFFFFFFFFU;
//scmd.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
//scmd.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS;
//scmd.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
scmd.DataMode = HAL_OSPI_DATA_1_LINE;
scmd.NbData = 1U;
scmd.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
scmd.DummyCycles = 0U;
scmd.DQSMode = HAL_OSPI_DQS_DISABLE;
scmd.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
HAL_OSPI_Command(&ctxt[octospi].handle, &scmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
if( 1 )
{
OSPI_AutoPollingTypeDef poll;
poll.Match = 0x02U;
poll.Mask = 0x02U;
poll.MatchMode = HAL_OSPI_MATCH_MODE_AND;
poll.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE;
poll.Interval = 0x10U;
HAL_OSPI_AutoPolling(&ctxt[octospi].handle, &poll, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
}
else
{
uint8_t value;
HAL_OSPI_Receive(&ctxt[octospi].handle, &value, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
}
}
Any idea of what could be wrong ?
Thanks a lot.
Fabrice
Solved! Go to Solution.
2024-12-05 06:56 AM - edited 2024-12-05 06:58 AM
Hello @Fabrice_GIRARDOT,
The OCTOSPI interface may generate up to six extra dummy clock cycles after it reads the last data due to internal synchronization.
So, it is expected from the OCTOSPI sometimes to send extra clock cycles when making read operations. The OCTOSPI filters the received bytes and takes only the considered ones.
So, sending an extra clock cycle when reading the status register gives you always the status register with an updated state. It is not impacted the application or the memory. This behavior it is not impacting the OCTOSPI/Memory functionality.
This phenomenon is documented in RM0456.
Is my reply answer your request?
Thank you.
Kaouthar
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-12-05 06:56 AM - edited 2024-12-05 06:58 AM
Hello @Fabrice_GIRARDOT,
The OCTOSPI interface may generate up to six extra dummy clock cycles after it reads the last data due to internal synchronization.
So, it is expected from the OCTOSPI sometimes to send extra clock cycles when making read operations. The OCTOSPI filters the received bytes and takes only the considered ones.
So, sending an extra clock cycle when reading the status register gives you always the status register with an updated state. It is not impacted the application or the memory. This behavior it is not impacting the OCTOSPI/Memory functionality.
This phenomenon is documented in RM0456.
Is my reply answer your request?
Thank you.
Kaouthar
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-12-09 03:10 AM