Skip to main content
Visitor II
April 17, 2024
Question

STM32H QSPI LL Driver

  • April 17, 2024
  • 1 reply
  • 1307 views

Hello,

I'm trying to implement the QSPI interface to a micron device utilizing the OSPI hardware with LL kinda of driver (It's not available so I tried to write it by myself). I configured the OSPI and OSPIM registers and from signals that I see on my custom board they're toggling. However, as an initial test I want to read the Device ID from "MT25QL128ABB1ESE" with command "0x9E" in 1-0-1 mode.

 

Initially I tried to keep the FIFO disabled (FTHRES = 0) however, after 2 bytes the FT flag won't set while I want to read five bytes. Then I decided to put the FIFO flag for 5 bytes (FTHRES = 4) and run it this way.

 

ErrorStatus MT25QCheck ( OSPIHandler *OSPI_Handler)

{

ErrorStatus Status = SUCCESS;

uint8_t Data[20];

 

/* Configure for instruction+read in 1-0-1 mode */

OSPI_RegularCmdTypeDef RegularCmdStruct = {0};

RegularCmdStruct.OperationType = LL_OSPI_OPTYPE_INDIRECT;

RegularCmdStruct.InstructionMode = LL_OSPI_INSTRUCTION_1_LINE;

RegularCmdStruct.InstructionSize = LL_OSPI_INSTRUCTION_8_BITS;

RegularCmdStruct.DataMode = LL_OSPI_DATA_1_LINE;

RegularCmdStruct.NbData = 5;

RegularCmdStruct.DummyCycles = DefaultDummyCycles;

RegularCmdStruct.Instruction = READID;

LL_OSPI_FTHRES_Change (OSPI_Handler->OSPI_Peripheral, 5);

Status += LL_OSPI_ReceiveRegIndirect ( OSPI_Handler->OSPI_Peripheral, &RegularCmdStruct, Data);

return Status;

}

 

/* Receive status */

ErrorStatus LL_OSPI_ReceiveRegIndirect ( OCTOSPI_TypeDef *OSPIx, OSPI_RegularCmdTypeDef *RegularCmdStruct, uint8_t *Data)

{

ErrorStatus Status = SUCCESS;

uint32_t i=0;

uint32_t Temp;

 

/* Wait till busy flag is reset */

while (__OSPI_GET_FLAG( OSPIx, LL_OSPI_FLAG_BUSY) == SET);

 

/* Put the functional mode on Indirect Read */

MODIFY_REG( OSPIx->CR, OCTOSPI_CR_FMODE_Msk, LL_OSPI_FMODE_INDIRECT_READ);

 

/* Modify the number of bytes to be exchanged */

MODIFY_REG( (OSPIx->DLR), OCTOSPI_DLR_DL_Msk, (RegularCmdStruct->NbData - 1U));

 

/* Config Transaction */

Status += OSPI_ConfigTransaction ( OSPIx, RegularCmdStruct);

 

/* Send instruction */

OSPIx->IR = RegularCmdStruct->Instruction;

 

/* Wait till fifo threshold is set to read data */

while (__OSPI_GET_FLAG( OSPIx, LL_OSPI_FLAG_FT) == RESET);

 

do

{

/* Receive register data */

Temp = OSPIx->DR;

Data [i] = (uint8_t) Temp;

i = i+1;

} while (i < RegularCmdStruct->NbData);

 

/* so wait until TC flag is set to go back in idle state */

while (__OSPI_GET_FLAG( OSPIx, LL_OSPI_FLAG_TC) == RESET);

 

/* Clear transfer complete flag */

__OSPI_CLEAR_FLAG( OSPIx, LL_OSPI_FLAG_TC);

 

/* Return function status */

return Status;

}

 

The code runs to the end but returns the wrong data. I debugged it with JTAG probe and found
that while the FIFO flag sets correctly and before putting the DR register in Temp variable
SR->FLEVEL is at 5, after the first read it goes to zero! Isn't it the case that if I have
5 bytes in FIFO I should access the OSPI->DR, 5 times? I put the data temporarily in Temp
variable to make sure that I don't read 4 bytes at a time.

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    May 3, 2024

    Hello @OGhad.1 ,

    Which STM32H7 are you using?

    Could you please check the STM32H7 errata sheet?

    May AN5050 help you.

    Thank you.

    Kaouthar