cancel
Showing results for 
Search instead for 
Did you mean: 

UART and DMA not working correctly... I only get one char and than DMA stops.

MechatronikMonkey
Associate II

I set up DMA with USART in CubeMX 5.0.1 but it is not working correctly....

When calling

HAL_UART_Receive_DMA(&huart1,USARTBuffer,10);

Only the first [0] field of my array changes and contains a received char. All other fields stay untouched. After that I can do what ever I want, DMA seems not to work until I reset. Than I get once again only one char.

What am I doing wrong?

Contents of my usart.c

UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
 
/* USART1 init function */
 
void MX_USART1_UART_Init(void)
{
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
 
  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration    
    PA10     ------> USART1_RX
    PA9     ------> USART1_TX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    /* USART1 DMA Init */
    /* USART1_RX Init */
    hdma_usart1_rx.Instance = DMA1_Channel3;
    hdma_usart1_rx.Init.Request = DMA_REQUEST_3;
    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_usart1_rx.Init.Mode = DMA_NORMAL;
    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
 
  /* USER CODE BEGIN USART1_MspInit 1 */
 
  /* USER CODE END USART1_MspInit 1 */
  }
}
 
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
 
  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */
 
  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();
  
    /**USART1 GPIO Configuration    
    PA10     ------> USART1_RX
    PA9     ------> USART1_TX 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10|GPIO_PIN_9);
 
    /* USART1 DMA DeInit */
    HAL_DMA_DeInit(uartHandle->hdmarx);
  /* USER CODE BEGIN USART1_MspDeInit 1 */
 
  /* USER CODE END USART1_MspDeInit 1 */
  }
} 

And the contents of dma.c

void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Channel2_3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
 
}

1 ACCEPTED SOLUTION

Accepted Solutions

Thanks guys, you where helping me... first of all... it was a hardware bug... i was meassuring the UART RX signal before a termination resistor and so I got a signal.

BUT... i had a small copper-hair which was shortening the RX to GND... I do not understand why I got the first char, but after removing this tiny copper hair, the DMA runs as expected!!!

So the hint, to watch the RX line did help me to trigger me to watch the hardware again!

My thoughts where digital... when one char arrives, there can be no problem with the hardware... but that was wrong.

Thanks guys!

View solution in original post

3 REPLIES 3

Make sure there are characters arriving at the Rx pin.

If you observe the UART registers in debugger, stop doing it.

Read out and check/post the UART and relevant DMA registers, especially the status registers.

JW

Bob S
Principal

Any kind of error from the USART will abort the DMA transfer. Do you implement a HAL_UART_ErrorCallback()? If not, you should. From that, call HAL_UART_GetError() and see what error you are getting. If any.

Thanks guys, you where helping me... first of all... it was a hardware bug... i was meassuring the UART RX signal before a termination resistor and so I got a signal.

BUT... i had a small copper-hair which was shortening the RX to GND... I do not understand why I got the first char, but after removing this tiny copper hair, the DMA runs as expected!!!

So the hint, to watch the RX line did help me to trigger me to watch the hardware again!

My thoughts where digital... when one char arrives, there can be no problem with the hardware... but that was wrong.

Thanks guys!