cancel
Showing results for 
Search instead for 
Did you mean: 

How to enable HAL_UART_RxCpltCallback?

DBroo.1
Associate III

I've reviewed numerous similar posts and the UART_TwoBoards_ComIT example, but have found no solution. My code is being generated by Cube 6.6.1 for the STM32F446. The UART5 Global Interrupt is enabled. My code and the example code both contain UART5_IRQHandler(void), HAL_UART_IRQHandler() and HAL_UART_RxCpltCallback(). After my app calls HAL_UART_Receive_IT(), UART5_IRQHandler() is being called, presumably with every character received. But HAL_UART_RxCpltCallback() is never called. I am only interested in HAL_UART_RxCpltCallback() after all data has been received. I've found no instructions on how to enable HAL_UART_RxCpltCallback(). It seems to happen magically. Must UART5_IRQHandler(void) interrupt be enabled to get HAL_UART_RxCpltCallback() enabled? And how do I get HAL_UART_RxCpltCallback() to work? Thanks.

9 REPLIES 9

Supposed to call for IRQ or DMA variants when the bytes remaining is zero. All source is available

If USE_HAL_UART_REGISTER_CALLBACKS is defined you can register the function.

Otherwise check you've got linkage, and you're not using .CPP or C++ compilation.

Your IRQHandler should call into the HAL stack, it should manage the dispatch.

Callback's are done under interrupt context, so mustn't block.

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

I just implemented the Callback by adding huart5.RxCpltCallback = RxCpltCallback; to my call to HAL_UART_Init(&huart5), and also created the actual RxCpltCallback function. RxCpltCallback() is still not being called. And USE_HAL_UART_REGISTER_CALLBACKS is defined in Cube.

Karl Yamashita
Lead II

You say you call HAL_UART_Receive_IT() but you don't show the arguments that you pass it. Knowing the arguments will show what you're expecting in order for it to interrupt. Also what data are you expecting to receive?

DBroo.1
Associate III

All parameters are valid. I am passing in a buffer and the size of that buffer, which is the same size as the expected data. The HAL manual implies that HAL_UART_Receive_IT() will generate an interrupt after all of those bytes are received. But I stepped through the HAL driver code and see no code to achieve that. Instead, UART5_IRQHandler() is called with every character received, I get no Callback interrupt. I noticed that the last expected character is in the Data Register. This code is running as though I need to read the Data Register with every UART5_IRQHandler().

Karl Yamashita
Lead II

If UART5_IRQHandler() is called on every character received instead of a larger set of bytes, then you didn't set up HAL_UART_Receive_IT() correctly. Paste some snippets of the code.

Karl Yamashita
Lead II

See attached project. It's just bare minimum to see if the debugger breaks inside the HAL_UART_RxCpltCallback() callback after receiving at least 20 characters, which it does and also turns on an LED. It doesn't handle errors afterwards. I've tested on a STM32F407 but it uses the same HAL UART drivers as the STM32F446.

DBroo.1
Associate III

Before seeing your last two comments, I switched to HAL_UART_Receive_DMA() to see if that would work. It seems to work similarly to HAL_UART_Receive_IT(). No call to HAL_UART_RxCpltCallback. Sorry to switch gears on you.

I then set a breakpoint at memcpy(). The code stops there. RxBuffer contains the 153 bytes of data I am expecting, followed by the NULL char! Then, to address your buffer/buffersize concerns, I adjusted the size of RxBuffer and the size passed in my call to HAL_UART_Receive_DMA() up and down to make the received contents of RxBuffer look just right. But still no call to HAL_UART_RxCpltCallback(). I checked my Cube settings against yours and they look the same.

 char RxBuffer[RESPONSE_STRING_FULL_SIZE] = {0};

 char TX_DEBUG_UART_Buffer[MAX_RX_SIZE] = {0};

 UART_HandleTypeDef* pDebugPort = debugPortGet_pUart(pBLE->m_pUartDebug);

 oosmos_ThreadBegin();

  pBLE->m_HalStatus = HAL_UART_Transmit(pBLE->m_pUart, (uint8_t *)pBLE->m_DataPacketToSend, strlen(pBLE->m_DataPacketToSend), 250);

  if (pBLE->m_HalStatus != HAL_OK)

  {

   oosmos_PushEventCode(pBLE, evRetry);

  }

  else

  {

   pBLE->m_HalStatus = HAL_UART_Receive_DMA(pBLE->m_pUart, (uint8_t *)(RxBuffer), sizeof(RxBuffer) - 1);

   memcpy(pBLE->m_ResponseStringFull, RxBuffer, sizeof(RxBuffer));

extern void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

{

 if(UartHandle->Instance == huart5.Instance)

 {

  DataReceived = true;

 }

}

Karl Yamashita
Lead II

Initialize your HAL_UART_Receive_IT() to receive 1 byte for now.

Put some breakpoints in the file stm32f4xx_hal_uart.c at line 2373 and 2375. Run the debugger and send some characters. You should break at each line.

0693W00000WHVwcQAH.png 

Then step through the code which will go to stm32fxx_hal_uart.c and your huart variable should look similar to this except addresses will be different.

0693W00000WHVxpQAH.png 

and from there you should be able to step until you reach HAL_UART_RxCpltCallback().

0693W00000WHVxGQAX.png 

What's the issue regarding the c++ compiler? I'm trying to write a uart reciever using c++ but can't find any information on the issue you're hinting at.