cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H QSPI LL Driver

OGhad.1
Associate

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.

1 REPLY 1
KDJEM.1
ST Employee

Hello @OGhad.1 ,

Which STM32H7 are you using?

Could you please check the STM32H7 errata sheet?

May AN5050 help you.

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.