cancel
Showing results for 
Search instead for 
Did you mean: 

OCTOSPI: HAL_OSPI_AutoPolling() seems to read 1 extra byte

Fabrice_GIRARDOT
Associate II

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.

a.png

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 :

TEK00090.PNG

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 :

TEK00089.PNG

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

 

1 ACCEPTED SOLUTION

Accepted Solutions
KDJEM.1
ST Employee

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

KDJEM1_0-1733409918637.png

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.

View solution in original post

2 REPLIES 2
KDJEM.1
ST Employee

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

KDJEM1_0-1733409918637.png

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.

Hello @KDJEM.1 

Your reply fully answers my request.

Thanks a lot !