Skip to main content
RFlod.2
Associate III
July 3, 2026
Question

UART DMA collision STML4

  • July 3, 2026
  • 0 replies
  • 3 views

I have two concurrent UART DMA RX running in STM32l431.

 

UART2 is running all the time and UART3 is started when a command is sent and waiting for data.

 

Both of them works, but when I try to make a new DMA transfer on one of them the other stops which I do not want. Why does this happens?

 

Here is the initiation:

DMA_HandleTypeDef hdma_rx2;
DMA_HandleTypeDef hdma_rx3;
DMA_HandleTypeDef hdma_lrx1;

DMA_InitTypeDef DMA_InitStructure;
void HW_DMA_Init()
{
__HAL_RCC_DMA1_FORCE_RESET();
__HAL_RCC_DMA1_RELEASE_RESET();
__HAL_RCC_DMA1_CLK_ENABLE();

__HAL_RCC_DMA2_FORCE_RESET();
__HAL_RCC_DMA2_RELEASE_RESET();
__HAL_RCC_DMA2_CLK_ENABLE();

currentDMABufferWrite = 1;
currentDMABufferRead = 0;

dmaLen1 = 0;
dmaLen2 = 0;
dmaHasData1 = false;
dmaHasData2 = false;

/* Configure the DMA handler for reception process */
hdma_rx2.Instance = DMA1_Channel6;
hdma_rx2.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx2.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx2.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx2.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx2.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx2.Init.Mode = DMA_CIRCULAR;
hdma_rx2.Init.Priority = DMA_PRIORITY_HIGH;
hdma_rx2.Init.Request = DMA_REQUEST_2;
HAL_DMA_Init(&hdma_rx2);

/* Associate the initialized DMA handle to the the UART handle */
__HAL_LINKDMA(&UartHandle2, hdmarx, hdma_rx2);
HAL_StatusTypeDef err;
err = HAL_DMA_Start(&hdma_rx2, (uint32_t)&UartHandle2.Instance->RDR, (uint32_t)dmaData1, DMA1_SIZE); //OBS!!! kolla att den alltid kör
if(err != HAL_OK)
{
printf("DMA err %d\n\r", err);
}
HAL_UART_Receive_DMA(&UartHandle2, (uint8_t *)dmaData1, DMA1_SIZE);

hdma_rx3.Instance = DMA1_Channel3;
hdma_rx3.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx3.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx3.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx3.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx3.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx3.Init.Mode = DMA_NORMAL;
hdma_rx3.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_rx3.Init.Request = DMA_REQUEST_2;
HAL_DMA_Init(&hdma_rx3);

/* Associate the initialized DMA handle to the the UART handle */
__HAL_LINKDMA(&UartHandle3, hdmarx, hdma_rx3);

LL_DMA_SetPeriphRequest(DMA2, LL_DMA_CHANNEL_7, LL_DMA_REQUEST_4);
LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_CHANNEL_7, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
LL_DMA_SetChannelPriorityLevel(DMA2, LL_DMA_CHANNEL_7, LL_DMA_PRIORITY_MEDIUM);
LL_DMA_SetMode(DMA2, LL_DMA_CHANNEL_7, LL_DMA_MODE_NORMAL);
LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_CHANNEL_7, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_CHANNEL_7, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA2, LL_DMA_CHANNEL_7, LL_DMA_PDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA2, LL_DMA_CHANNEL_7, LL_DMA_MDATAALIGN_BYTE);

}

 

 

When I run these functions:

HW_DMA_DisableUart3Rx();   
HW_DMA_NewUart3Rx(response, RESPONE_LENGTH);

 

UART2 DMA transfer stops.



void HW_DMA_NewUart3Rx(char databuffer[], uint32_t size)
{
HW_DMA_CheckErrorflags();
//LL_USART_ClearFlag_ORE(USART3);
HAL_StatusTypeDef err = HAL_DMA_Start(&hdma_rx3, (uint32_t)&UartHandle3.Instance->RDR, (uint32_t)databuffer, size); //OBS!!! kolla att den alltid kör
if(err != HAL_OK)
{
printf("DMA err %d\n\r", err);
}

if(HAL_UART_Receive_DMA(&UartHandle3, (uint8_t *)databuffer, size) != HAL_OK)
{
printf("DMA fel\n\r");
}
}

void HW_DMA_DisableUart3Rx()
{
HAL_UART_DMAStop(&UartHandle3);
//DMA_Cmd(DMA1_Stream1, DISABLE); // DMA_Cmd(DMA1_Channel3, DISABLE);
}

bool HW_DMA_CheckErrorflags()
{
//if(DMA1->HIFCR || DMA1->HISR || DMA1->LIFCR || DMA1->LISR)
//if(DMA_GetFlagStatus(DMA1_Stream5, DMA_IT_TCIF5) ||
// DMA_GetFlagStatus(DMA1_Stream5, DMA_IT_HTIF5) ||
if(LL_USART_IsActiveFlag_ORE(USART2) != 0)
{
LL_USART_ClearFlag_ORE(USART2);
}
if(LL_USART_IsActiveFlag_ORE(USART3) != 0)
{
LL_USART_ClearFlag_ORE(USART3);
}

if(LL_USART_IsActiveFlag_ORE(LPUART1) != 0)
{
LL_USART_ClearFlag_ORE(LPUART1);
}

if( HAL_DMA_GetError(&hdma_rx2) != 0 || HAL_DMA_GetError(&hdma_rx3) != 0)
{
printf("DMA fel: %lu, %lu\n\r", HAL_DMA_GetError(&hdma_rx2), HAL_DMA_GetError(&hdma_rx3));

HAL_DMA_Abort(&hdma_rx2);
HAL_DMA_Abort(&hdma_rx3);

__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_TE6);
__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_HT6);
__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_TC6);
__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_GL6);

__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_TE3);
__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_HT3);
__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_TC3);
__HAL_DMA_CLEAR_FLAG(&hdma_rx2, DMA_FLAG_GL3);


HW_DMA_Init();
return false;
}
if( HAL_DMA_GetError(&hdma_lrx1) != 0)
{
printf("DMA l1 fel: %lu \n\r", HAL_DMA_GetError(&hdma_lrx1));

HAL_DMA_Abort(&hdma_lrx1);

__HAL_DMA_CLEAR_FLAG(&hdma_lrx1, DMA_FLAG_TE7);
__HAL_DMA_CLEAR_FLAG(&hdma_lrx1, DMA_FLAG_HT7);
__HAL_DMA_CLEAR_FLAG(&hdma_lrx1, DMA_FLAG_TC7);
__HAL_DMA_CLEAR_FLAG(&hdma_lrx1, DMA_FLAG_GL7);

HW_DMA_Init();
return false;
}
return true;

}