2020-12-01 06:47 AM
Hi,
The example DMAMUX_RequestGen works perfectly on my STM32H755 board and now I'm trying to modify it so it uses the DMA1 instead of the BDMA. I need that because at the end I would like to trigger a SPI5 RX.
Unfortunately I cannot make it work, that means I don't see the output pin toggling when EXTI0 is changing. I have no error during the configuration. And no DMA error neither.
Here is what I changed form the example:
What did I forget? What shall I check?
This is the source code:
/*Buffer location and size should aligned to cache line size (32 bytes) */
/* Use SRAM4 for BDMA, or SRAM1 for DMA1 */
#if defined(__ICCARM__)
#ifdef USE_BDMA
#pragma location = 0x38000000
#else
#pragma location = 0x30000000
#endif
uint32_t SRC_Buffer_LED1_Toggle[2] =
{
0, /*Value for LED 1 ON */
GPIO_PIN_10 /*Value for LED 1 OFF */
};
#endif
static void init_and_start_exti0_dma()
{
HAL_StatusTypeDef ret;
HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams = {0};
/* Configure the PF10 pin */
__HAL_RCC_GPIOF_CLK_ENABLE();
GPIO_InitTypeDef gpio_init_structure;
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
gpio_init_structure.Pin = GPIO_PIN_10;
HAL_GPIO_Init(GPIOF, &gpio_init_structure);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);
/*##-2- Configure the DMA ##################################################*/
/* Enable BDMA and DMA1 clock */
#ifdef USE_BDMA
__HAL_RCC_BDMA_CLK_ENABLE();
#else
__HAL_RCC_D2SRAM1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
#endif
/* Configure the DMA handler for Transmission process */
/* DMA mode is set to circular for an infinite DMA transfer */
#ifdef USE_BDMA
DMA_Handle.Instance = BDMA_Channel0;
DMA_Handle.Init.Request = BDMA_REQUEST_GENERATOR0;
#else
DMA_Handle.Instance = DMA1_Stream0;
DMA_Handle.Init.Request = DMA_REQUEST_GENERATOR0;
#endif
DMA_Handle.Init.Direction = DMA_MEMORY_TO_PERIPH;
DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE;
DMA_Handle.Init.MemInc = DMA_MINC_ENABLE;
DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
DMA_Handle.Init.Mode = DMA_CIRCULAR;
DMA_Handle.Init.Priority = DMA_PRIORITY_LOW;
DMA_Handle.Init.FIFOMode = 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;
/* Initialize the DMA with for Transmission process */
ret = HAL_DMA_Init(&DMA_Handle);
assert(ret == HAL_OK);
/* Select Callbacks functions called after Transfer complete and Transfer error */
HAL_DMA_RegisterCallback(&DMA_Handle, HAL_DMA_XFER_CPLT_CB_ID, NULL);
HAL_DMA_RegisterCallback(&DMA_Handle, HAL_DMA_XFER_ERROR_CB_ID, HAL_TransferError);
/* NVIC configuration for DMA transfer complete interrupt*/
#ifdef USE_BDMA
HAL_NVIC_SetPriority(BDMA_Channel0_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
#else
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
#endif
/*##-4- Configure and enable the EXTI0 used as DMA external request signal #####*/
EXTI0_IRQHandler_Config();
/*##-3- Configure and enable the DMAMUX Request generator ####################*/
#ifdef USE_BDMA
dmamux_ReqGenParams.SignalID = HAL_DMAMUX2_REQ_GEN_EXTI0; /* External request signal is EXTI0 signal */
#else
dmamux_ReqGenParams.SignalID = HAL_DMAMUX1_REQ_GEN_EXTI0; /* External request signal is EXTI0 signal */
#endif
dmamux_ReqGenParams.Polarity = HAL_DMAMUX_REQ_GEN_FALLING; /* External request signal edge is Falling */
dmamux_ReqGenParams.RequestNumber = 1; /* 1 requests on each edge of the external request signal */
ret = HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handle, &dmamux_ReqGenParams);
assert(ret == HAL_OK);
/* NVIC configuration for DMAMUX request generator overrun errors*/
#ifdef USE_BDMA
HAL_NVIC_SetPriority(DMAMUX2_OVR_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMAMUX2_OVR_IRQn);
#else
HAL_NVIC_SetPriority(DMAMUX1_OVR_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMAMUX1_OVR_IRQn);
#endif
ret = HAL_DMAEx_EnableMuxRequestGenerator(&DMA_Handle);
assert(ret == HAL_OK);
/*##-5- Start the DMA transfer ################################################*/
/* DMA source buffer is SRC_BUFFER_LED1_TOGGLE containing values to be written
to GPIOF ODR register in order to turn LED1 On/Off each time comes a request from the DMAMUX request generator */
ret = HAL_DMA_Start_IT(&DMA_Handle, (uint32_t)SRC_Buffer_LED1_Toggle, (uint32_t)&GPIOF->ODR, 2);
assert(ret == HAL_OK);
}
Thank you for any help.
Solved! Go to Solution.
2021-01-03 11:47 PM
This is the answer I got from ST:
The behaviour with the EXTI0 is different in domain D3 (triggering BDMA from EXTI0). This is due to the fact that the domain D3 is designed for autonomous mode where both CPU core are OFF. The EXTI0 can only be used as an event. It is automatically cleared.
With DMAMUX1 in domain D2, if a trigger is needed without executing an IRQ handler, the EXTI0 is not the good one. A timer or a DMA event has to be used instead.
More information can be found in the Release Manual (EXTI, DMAMUX, PWR sections) and AN5224 (STM32 DMAMUX: the DMA request router).
2020-12-01 07:43 AM
Read out and check/post content of DMAMUX/DMA registers, perhaps also relevant GPIO and whichever register steers the given EXTI input (I don't use the 'H7, in most families it's in SYSCFG).
JW
2020-12-01 08:09 AM
2021-01-03 11:47 PM
This is the answer I got from ST:
The behaviour with the EXTI0 is different in domain D3 (triggering BDMA from EXTI0). This is due to the fact that the domain D3 is designed for autonomous mode where both CPU core are OFF. The EXTI0 can only be used as an event. It is automatically cleared.
With DMAMUX1 in domain D2, if a trigger is needed without executing an IRQ handler, the EXTI0 is not the good one. A timer or a DMA event has to be used instead.
More information can be found in the Release Manual (EXTI, DMAMUX, PWR sections) and AN5224 (STM32 DMAMUX: the DMA request router).