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