2021-11-03 07:54 AM
Hi! I'm trying to use the following function:
HAL_UARTEx_ReceiveToIdle_IT(&hlpuart1, lpuartRXbuffer, 64);
I've seen a few example codes using it but otherwise google shows nothing when I search for it. I think I should get some callback but I cannot figure what should it be. I tried the following:
void HAL_UARTEx_RxEventCalllback(UART_HandleTypeDef *huart, uint16_t Size)
{
}
But there is no response.
I'm new to the STM32 software environment, coming from Arduino and Atmel so any advice where to find such information helps a lot.
Solved! Go to Solution.
2021-11-03 09:08 AM
> Is there any obvious beginner mistake?
Yes, there is - the spelling of the function name... ;)
2021-11-03 08:07 AM
HAL_UARTEx_ReceiveToIdle_IT is relatively new compared to the other UART functions which explains the lack of examples.
HAL_UARTEx_RxEventCalllback HAL_UARTEx_RxEventCallback is called when the idle condition happens exactly here in the code:
If that's not happening, you would need to dig deeper. Ensure the HAL_UART_IRQHandler is getting called. Ensure the idle flag is getting set and the interrupt is enabled. When idle happens, ensure the IRQ handler is called and handled appropriately.
2021-11-03 08:23 AM
Well then I have to dig deeper. I have interrupts enabled and the regular "HAL_UART_RxCpltCallback" works perfectly when I use "HAL_UART_Receive_IT".
I'll paste a few pieces of my code here, maybe it's just my beginner mistake:
In the main, after initializing the peripherals (init generated by the IDE), I use
HAL_UARTEx_ReceiveToIdle_IT(&hlpuart1, lpuartRXbuffer, 64);
Then there is the callback, before the main, in the User Code 0 section:
void HAL_UARTEx_RxEventCalllback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == LPUART1)
{
HAL_UART_Transmit_IT(&hlpuart1, lpuartRXbuffer, Size);
HAL_UARTEx_ReceiveToIdle_IT(&hlpuart1, lpuartRXbuffer, 64);
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
//echo = 1;
}
}
Is there any obvious beginner mistake?
2021-11-03 09:08 AM
> Is there any obvious beginner mistake?
Yes, there is - the spelling of the function name... ;)
2021-11-03 10:00 AM
Thank you! I feel really stupid now. :)
2023-04-12 02:53 AM
Hello
I used the same function and it works. BUT it works only at the moment when I program it when I disconnect stlink and restart the system it doesn't work (No response from callback function)... Does anybody knows what happens here ?
2024-03-06 10:03 AM
I've been fighting with STM43F429. I have what I am working on functioning, but it took a lot of work.
I use the idle interrupt to receive data. I got similar code working in late 2020 and using ST Micro's APIs, but have had to revisit ST Micro's UART API in the last few weeks after starting a new project and updating to 1.14.1.
I am using the idle interrupt and the function HAL_UARTEx_ReceiveToIdle_IT(&huart4, pRdBuffer, size) to receive my data.
In void UART4_IRQHandler(void), I replaced...
if (__HAL_UART_GET_FLAG (&huart4, UART_FLAG_IDLE))
{
__HAL_UART_CLEAR_IDLEFLAG (&huart4);
HAL_UART_RxCpltCallback (&huart4);
}
with
if((registerValue & UART_FLAG_IDLE) == UART_FLAG_IDLE)
{
huart4.Instance->SR = registerValue & 0xFFFFFFEF;
HAL_UART_RxCpltCallback(&huart4);
}
So __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) only clears the PE flag. See line 540 of stm32f4xx_hal_uart.h to confirm for yourself.
In troubleshooting, I found more issues. Here is the excerpt I wrote to share my findings with my coworkers.
....in stm32f4xx_hal_uart.h lines 516 to 540. There is a set of macros that only clear the PE Flag, not the flags they report to clear.
They call the macro __HAL_UART_CLEAR_PEFLAG() It only (seemingly) clears the UART PE pending flag.
So the macro __HAL_UART_CLEAR_FEFLAG ostensibly clears the PE Flag,
__HAL_UART_CLEAR_NEFLAG ostensibly clears the PE Flag,
__HAL_UART_CLEAR_OREFLAG ostensibly clears the PE Flag, and
__HAL_UART_CLEAR_IDLEFLAG ostensibly clears the PE Flag.
Those macros call another macro __HAL_UART_CLEAR_PEFLAG() which doesn't seem to clear the PE flag.
In the original concept, ST Micro probably intended for HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) to be used for this. Examples of what they probably intended to do are shown immediately below.
HAL_UART_CLEAR_FLAG(__HANDLE__, UART_FLAG_FE)
HAL_UART_CLEAR_FLAG(__HANDLE__, UART_FLAG_NE)
HAL_UART_CLEAR_FLAG(__HANDLE__, UART_FLAG_ORE)
HAL_UART_CLEAR_FLAG(__HANDLE__, UART_FLAG_IDLE)and
HAL_UART_CLEAR_FLAG(__HANDLE__, UART_FLAG_PE)
Someone at ST Micro either made a series of cut-paste errors and/or didn't know what was going on. They seem to have never tested this or maybe they just never envisioned their API being used the way we're using it.
Hopefully this helps someone who is struggling. Hopefully, this helps ST Micro, too.
2024-03-06 11:51 AM - edited 2024-03-06 11:55 AM
@DanKlein Please start a new thread if you want to discuss another issue.
Rather than "fighting" with the STM32, read the good book. RM0090. The U(S)ART register description. There it says that PE flag can be cleared by a sequence: reading SR then reading or writing DR, *when RXNE is set*.
Flags IDLE, FE, ORE, NF are cleared by the same sequence: reading SR then reading or writing DR - but there's no condition "The software must wait for the RXNE flag to be set". None of these flags can be cleared by writing anything into SR.
__HAL_UART_CLEAR_PEFLAG indeed is implemented as read SR, then read DR. No writing SR.
Macros in stm32f4xx_hal_uart.h have comments that describe which flags they can read or clear.