2024-04-17 02:51 PM
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.
2024-05-03 12:46 AM