2021-08-01 01:07 PM
I'm currently playing around with the QSPI_ReadWrite_DMA example on an STM32F769I_EVAL board.
Link to example:
I'm testing the QSPI Reads and it generally seems to be working most of the time but is consistently hanging when I try to read values of 0x10000 or higher.
I don't a read command limitation on the SPI Flash chip that comes with the STM32F769I_EVAL so I 'm wondering if anyone has any idea what could be the issue? Seems like a very particular boundary to stop working at. Not sure if it's an STM32 related limit?
Thanks!
Solved! Go to Solution.
2021-08-05 09:45 AM
2021-08-02 03:53 PM
There is not a 64kB limit to the QSPI address space and the chip on there has much more than 64kB of capacity.
Debug the code, where does it hang? Be specific.
2021-08-02 04:15 PM
DMA might have a 16-bit limit on the transfer count.
Many of the current QSPI NOR Flash have a 64KB block size. Usually a 256-byte page alignment/limit.
2021-08-02 11:11 PM
Thanks I'll try to give a bit more information.
From what I can see the last call made was HAL_QSPI_Receive_DMA which returns HAL_OK but the HAL_QSPI_RxCpltCallback never gets called which results in the while loop spinning indefinitely.
If I were to read the same range using the blocking version HAL_QSPI_Receive I see no issue, this is my current workaround.
My SPI Commands configurations are as follows:
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.AddressSize = QSPI_ADDRESS_24_BITS;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
sCommand.Address = address;
sCommand.DataMode = QSPI_DATA_4_LINES;
sCommand.NbData = bufferSizeBytes;
The DMA is configured as such:
hdma.Init.Channel = QSPI_DMA_CHANNEL;
hdma.Init.PeriphInc = DMA_PINC_DISABLE;
hdma.Init.MemInc = DMA_MINC_ENABLE;
hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma.Init.Mode = DMA_NORMAL;
hdma.Init.Priority = DMA_PRIORITY_LOW;
hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* FIFO mode disabled */
hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma.Init.MemBurst = DMA_MBURST_SINGLE; /* Memory burst */
hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Peripheral burst */
hdma.Instance = QSPI_DMA_INSTANCE;
2021-08-03 06:55 AM
Okay. And where is your HAL_QSPI_Receive_DMA call? Are you trying to read more than 65535 bytes at a time?
2021-08-05 08:40 AM
> Are you trying to read more than 65535 bytes at a time?
Yes, if I try to read more than 65535 then I will never get the RxCplt flag set meaning the code waits indefinitely for the flag to be set.
The HAL_QSPI_Receive_DMA call occurs AFTER:
Below is a snippet of the code (basically from the STM32 Example I mentioned in my first post): The difference is that the BUFFERSIZE is 0x10000 or greater when it fails.
/**
Comments:
StatusMatch and RxCplt are globals being set by the QSPI callback functions
*/
while(1)
{
switch(step)
{
StatusMatch = 0;
/* Configure automatic polling mode to wait for end of program ----- */
QSPI_AutoPollingMemReady(&QSPIHandle);
step++;
}
break;
case 4:
if(StatusMatch != 0)
{
StatusMatch = 0;
RxCplt = 0;
/* Configure Volatile Configuration register (with new dummy cycles) */
QSPI_DummyCyclesCfg(&QSPIHandle);
/* Reading Sequence ------------------------------------------------ */
sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (HAL_QSPI_Receive_DMA(&QSPIHandle, aRxBuffer) != HAL_OK)
{
Error_Handler();
}
step++;
}
break;
case 5:
if (RxCplt != 0)
{
RxCplt = 0;
/* Result comparison ----------------------------------------------- */
for (index = 0; index < BUFFERSIZE; index++)
{
if (aRxBuffer[index] != aTxBuffer[index])
{
BSP_LED_On(LED2);
}
}
BSP_LED_Toggle(LED1);
address += QSPI_PAGE_SIZE;
if(address >= QSPI_END_ADDR)
{
address = 0;
}
step = 0;
}
break;
default :
Error_Handler();
}
}
2021-08-05 09:39 AM
Doesn't the DMA unit have a 16-bit transfer count limit?
For byte transfers that would be 64KB (perhaps less one byte)
Use HALF WORD or WORD transfers for larger transactions, and make sure your buffers are suitably aligned or decompose the transfers until they can be.
2021-08-05 09:45 AM
2021-08-05 10:03 PM
Thank you for your help, sorry I should have checked the reference manual closer, this explains things I will check this out.