UART DMA collision STML4
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;
}
