Skip to main content
MechatronikMonkey
Associate II
January 31, 2019
Solved

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

  • January 31, 2019
  • 2 replies
  • 1795 views

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);
 
}

This topic has been closed for replies.
Best answer by MechatronikMonkey

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!

2 replies

waclawek.jan
Super User
January 31, 2019

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

MechatronikMonkey
MechatronikMonkeyAuthorBest answer
Associate II
February 1, 2019

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!

Bob S
Super User
January 31, 2019

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.