2020-07-10 02:26 AM
I've referred STM32F769I_EVAL QSPI with DMA source code and implemented same way for STM32F767 but its not working. can anyone provide the sample code for STM32f767 QSPI with DMA
2020-07-14 11:05 AM
Hi
I am using it in indirect mode for a "simple", 4 lines SPI.
Once configured, CubeMX generates the following code in “MX_QUADSPI_Init�?
….
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 64;
hqspi.Init.FifoThreshold = 32;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
hqspi.Init.FlashSize = 1;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
if (HAL_QSPI_Init(&hqspi) != HAL_OK)
{
Error_Handler();
}
To that end, I have added:
hqspi.Instance->DLR=NumberOfBytes;//set number of bytes to read\write per CS. The number of clks are 2x(Value+1)
hqspi.Instance->DCR|=0x001F0000;//Flash configuration register
hqspi.Instance->ABR=0;//alternate bytes registers
hqspi.Instance->CCR=0x07000000;//configure Indirect read mode, data on 4 lines DMA must be disabled first
hqspi.Instance->CR|=0x00200005;//enable DMA
when a read is required:
HAL_QSPI_Receive_DMA(&hqspi,buffer);
Where buffer is the DMA destination.
--Arnon
2020-07-20 04:14 AM
Thanks Arnon,
I've re-checked the configuration and settings. what I see is configuration parameters are changing in between function calls and because of this I get hard fault. My DMA settings are,
Configure common DMA parameters */
dma_handle.Init.Channel = QSPI_DMAx_CHANNEL;
//dma_handle.Init.Direction = DMA_MEMORY_TO_MEMORY;
dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;//ENABLE;
dma_handle.Init.MemInc = DMA_MINC_ENABLE;
dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;//DMA_PDATAALIGN_WORD;
dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;//DMA_MDATAALIGN_WORD;
dma_handle.Init.Mode = DMA_NORMAL;
dma_handle.Init.Priority = DMA_PRIORITY_LOW;//HIGH;
dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;//ENABLE;//DMA_FIFOMODE_DISABLE;
dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
dma_handle.Init.MemBurst = DMA_MBURST_SINGLE;
dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
dma_handle.Instance = QSPI_DMAx_STREAM;
/* Associate the DMA handle */
HAL_DMA_Init(&dma_handle);
__HAL_LINKDMA(hqspi, hdma, dma_handle);
/* Deinitialize the stream for new transfer */
//HAL_DMA_DeInit(&dma_handle);
/* Configure the DMA stream */
// HAL_DMA_Init(&dma_handle);
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(QSPI_DMAx_IRQn, 0x05, 0);
HAL_NVIC_EnableIRQ(QSPI_DMAx_IRQn);
but if I step debug through the code, at the end in function HAL_DMA_Start_IT values of SrcAddress and DstAddress are just 0. because of this I get hard fault. but I'm not able to find out why DMA settings are getting changed.
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
HAL_StatusTypeDef status = HAL_OK;
/* calculate DMA base and stream number */
DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
/* Check the parameters */
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
/* Process locked */
__HAL_LOCK(hdma);
if(HAL_DMA_STATE_READY == hdma->State)
{
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_BUSY;
/* Initialize the error code */
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
/* Configure the source, destination address and the data length */
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
/* Clear all interrupt flags at correct offset within the register */
regs->IFCR = 0x3FU << hdma->StreamIndex;
/* Enable Common interrupts*/
hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
hdma->Instance->FCR |= DMA_IT_FE;
if(hdma->XferHalfCpltCallback != NULL)
{
hdma->Instance->CR |= DMA_IT_HT;
}
/* Enable the Peripheral */
__HAL_DMA_ENABLE(hdma);
}
else
{
/* Process unlocked */
__HAL_UNLOCK(hdma);
/* Return error status */
status = HAL_BUSY;
}
return status;
}
2020-07-20 05:30 AM
any clue to....why DMA settings are changing in runtime?
2020-07-20 05:57 AM
Have you tried using the QSPI DMA functions?
They can be found at "stm32f7xx_hal_qspi.c"
For example, I am using the "HAL_QSPI_Receive_DMA" to initiate QSPI read. Source and destination are parameters to this function.
This function calls for HAL_DMA_Start_IT eventually.
--Arnon
2020-07-20 06:00 AM
debugged further and found....hard fault is raised at line hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); in function DMA_SetConfig
if I check DMA2D_CR control register bits 18 - 31 are reserved bits, then why we're clearing bit 19th bit of hdma->Instance->CR through DMA_SxCR_DBM(0x40000)
if I step debug this line it goes to HardFault_Handler function
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
/* Clear DBM bit */
hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
/* Configure DMA Stream data length */
hdma->Instance->NDTR = DataLength;
/* Memory to Peripheral */
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
{
/* Configure DMA Stream destination address */
hdma->Instance->PAR = DstAddress;
/* Configure DMA Stream source address */
hdma->Instance->M0AR = SrcAddress;
}
/* Peripheral to Memory */
else
{
/* Configure DMA Stream source address */
hdma->Instance->PAR = SrcAddress;
/* Configure DMA Stream destination address */
hdma->Instance->M0AR = DstAddress;
}
}
2020-07-20 06:11 AM
Hello Arnon,
Yes, I'm using QSPI DMA function HAL_QSPI_Transmit_DMA(&QSPIHandle, aTxBuffer) != HAL_OK for transmitting data...as this function was leading to hard fault....I've debugged it further and found hard fault is initiated at hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); line in function DMA_SetConfig which is called HAL_DMA_Start_IT