cancel
Showing results for 
Search instead for 
Did you mean: 

The function HAL_UART_RxCpltCallback won't be called in Nucleo F401RE

DMårt
Senior II

Hi!

I have a Nucleo F401RE that works great! But the problem I have is that the board cannot be call the function HAL_UART_RxCpltCallback after it has recieve its bytes.

I have:

  • Using DMA
  • Enable global interupt
  • Using USART2
  • Calling DMA inside HAL_UART_RxCpltCallback function
  • Using STM32CubeIDE 1.1.0 and firwire 1.24.2

I'm expecting a LED lamp to light up, the one in the function below. But it does not light up because the function won't be called, why?

But when I try to send some bytes via CuteCom software, nothing happens. Here is a minimal C-code from me.

This code waits until it have got 41 bytes, then this function will be called.

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
 
 
   HAL_GPIO_WritePin(Digital0_GPIO_Port, Digital0_Pin, 1); // If this method be called, then light up LED lamp
 
 
   // Convert ADC values to
 
   TXData[0] = (uint8_t) (ADCValues[0] >> 8);
 
   TXData[1] = (uint8_t) (ADCValues[0] & 0xFF);
 
   TXData[2] = (uint8_t) (ADCValues[1] >> 8);
 
   TXData[3] = (uint8_t) (ADCValues[1] & 0xFF);
 
   TXData[4] = (uint8_t) (ADCValues[2] >> 8);
 
   TXData[5] = (uint8_t) (ADCValues[2] & 0xFF);
 
   TXData[6] = (uint8_t) (ADCValues[3] >> 8);
 
   TXData[7] = (uint8_t) (ADCValues[3] & 0xFF);
 
   TXData[8] = (uint8_t) (ADCValues[4] >> 8);
 
   TXData[9] = (uint8_t) (ADCValues[4] & 0xFF);
 
   TXData[10] = (uint8_t) (ADCValues[5] >> 8);
 
   TXData[11] = (uint8_t) (ADCValues[5] & 0xFF);
 
 
   // Send data to JLoggerServer in about 5 milliseconds
 
   HAL_UART_Transmit(&huart2, TXData, sizeof(TXData) / sizeof(TXData[0]), 5);
 
 
   // Listen for a new receive
 
   HAL_UART_Receive_DMA(&huart2, RXData, sizeof(RXData) / sizeof(RXData[0]));
 
 
}

My USART2 and DMA configuration.

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{
 
  /* USER CODE BEGIN USART2_Init 0 */
 
  /* USER CODE END USART2_Init 0 */
 
  /* USER CODE BEGIN USART2_Init 1 */
 
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
 
  /* USER CODE END USART2_Init 2 */
 
}
 
/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Stream5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
 
}

And at the main function. I'm calling these functions as well.

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
 
   // Enable ADC1 AND UART RX with DMA
   HAL_ADC_Start_DMA(&hadc1, ADCValues, sizeof(ADCValues) / sizeof(ADCValues[0]));
   HAL_UART_Receive_DMA(&huart2, RXData, sizeof(RXData) / sizeof(RXData[0]));

The fields are declared as

uint32_t ADCValues[6];
uint8_t RXData[12 + 28 + 1]; // 12 = sliders, 28 = digitals, 1 = send state
uint8_t TXData[12];

I hope this information helps. Else, ask for more.

Best regards

1 ACCEPTED SOLUTION

Accepted Solutions
Mikhail Z
Senior II

You probably need to initialize DMA before UART in the main().

View solution in original post

9 REPLIES 9

Could be a host of things, you'll need to debug your situation.

It doesn't receive any data.

Errors in the receive side of the UART, ie framing, noise or parity.

Errors on the DMA side, addresses or otherwise.

Is there an error callback for UART or DMA?

Any of the buffer fill with data?

Any errors returned by the called functions?

IRQ Handlers defined and called/working?

Try with byte level UART IRQ

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi!

I don't have the equipment to check if there is nose or parity in the UART. But I tried to check if the DMA is working by code and it does!

if (HAL_UART_Receive_DMA(&huart2, RXData, sizeof(RXData) / sizeof(RXData[0])) == HAL_OK){
		HAL_GPIO_WritePin(Digital0_GPIO_Port, Digital0_Pin, 1); // It works!
}

And for the UART. No error here.

static void MX_USART2_UART_Init(void)
{
 
  /* USER CODE BEGIN USART2_Init 0 */
 
  /* USER CODE END USART2_Init 0 */
 
  /* USER CODE BEGIN USART2_Init 1 */
 
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }else{
	  HAL_GPIO_WritePin(Digital0_GPIO_Port, Digital0_Pin, 1); // 	It works!
  }
  /* USER CODE BEGIN USART2_Init 2 */
 
  /* USER CODE END USART2_Init 2 */
 
}

Sending from Nucleo -> PC works perfect

while (1)
  {
    /* USER CODE END WHILE */
	  HAL_UART_Transmit(&huart2, TXData, 3, 5); // This works
	  HAL_Delay(1000);
    /* USER CODE BEGIN 3 */
  }

It's also working to send data from PC -> Nucleo

while (1)
  {
    /* USER CODE END WHILE */
	  HAL_UART_Receive(&huart2, TXData, 1, 5);
	  if(TXData[0] == 50){
		  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1); // Flash LED 1 second
		  HAL_Delay(1000);
	  }
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
    /* USER CODE BEGIN 3 */
  }

So that confirms that the UART is OK. But why not the DMA?

How can I check if there is any errors for the DMA?

Thank you for your response.

EDIT:

I know the issue now! The function is not declared yet. How can I declare that function so DMA knows that it exist?

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_RxCpltCallback could be implemented in the user file
   */
 
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1); // Nothing happens here
}
/* USER CODE END 4 */

 The function is avaiable in stm32f4xx_hal_uart.c file.

/**
  * @brief  Rx Transfer completed callbacks.
  * @param  huart  Pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function should not be modified, when the callback is needed,
           the HAL_UART_RxCpltCallback could be implemented in the user file
   */
}

But if I hover the mouse over the function it looks like this

0690X00000Bvb5aQAB.png

I'm also got some weird errors on DMA C-code. These errors says Missing ';'

0690X00000Bvb5uQAB.png0690X00000Bvb5pQAB.png

0690X00000Bvb5kQAB.png

Mikhail Z
Senior II

You probably need to initialize DMA before UART in the main().

But I'm using STMCubeIDE. That should be generated by itself. Or is it a bug?

Thank you! That solved my issue. I init the functions like this

/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */

And I have version 1.24.2 and not 1.24.1 as in the thread you send me.

DMårt
Senior II

Can an employee of ST mark this thread as a bug in version 1.24.2 ?

Yes! I know. Se the answer above.