cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_RxCpltCallback not being called for USART1 and USART1_IRQHandler has no data

JSC4
Associate II

Hello,

I have an STM32L476G Evaluation board, and I'm trying to use USART1 to generate an interrupt on receiving characters. On the evaluation board, this is connected to the RS232 port, which I have a module, I transmit data to get a response back. I've hooked up a salae logic analyser and can see when I send the data, the response is being sent back.

2023-10-29 07_24_32-Logic 2 [Logic Pro 16 - Connected] [Session 2].png

From CubeMX I have enabled the USART1, with global interrupts, as well as in the project manager tab, I have selected in the advanced settings register callback for USART and UART.

In the code I write the line below, to receive and interrupt every character:

HAL_UART_Receive_IT(&huart1, rx_buffer, 1);

 

 

Then I transmit the string code I write the line below, to receive and interrupt every character:

while(HAL_UART_Transmit_IT(&huart1, atc, 4) != HAL_OK);

HAL_Delay(1000);

 

The function below gets called, however, HAL_UART_RxCpltCallback(UART_HandleType *huart) never gets called.

void USART1_IRQHandler(void)

{

/* USER CODE BEGIN USART1_IRQn 0 */

/* USER CODE END USART1_IRQn 0 */

HAL_UART_IRQHandler(&huart1);

/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}

 

When I debug and put a breakpoint in the USART_IRQHandler(void) function, there is no data in the buffer.

 

What is the problem with what I am doing and why is the data not being stored in the buffer? I am generating an interrupt as the USART_IRQHandler(void) is causing the breakpoint to stop, but there is no data in the buffer.

8 REPLIES 8
KnarfB
Principal III

Selecting "register callback" means, that you have to write code registering your own functions. The traditional way is not selecting that in which case you have to implement your own HAL_UART_RxCpltCallback (what yo did).

If you still encounter issues, step into HAL_UART_IRQHandler and let the code show you what's going on.

hth

KnarfB

JSC4
Associate II

Adding some debug of the TX buffer being populated with the "AT\r", but the RX buffer has a count of one, but the data is always zero. 

JSC4_0-1698580184662.png

 

Shouldn't be using the while() loops for the transmit, the IT function will return immediately. 

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

@Tesla DeLorean Ok that's fine, I've stopped doing that and still the interrupt gets triggered and no data shows when I debug

@KnarfB Ok so I've unset register callback for the usart/uart. Still not data is being shown in the buffer, and the HAL_UART_RxCpltCallback is not called. In the HAL_UART_IRQHandler this if statement gets skipped.

JSC4_0-1698581488203.png
The return of the function happens here:
JSC4_1-1698581545472.png

I attached the _hal_uart.c for reference.

KnarfB
Principal III

is rx_buffer a global variable? The pRxBufPtr variable in your above dump has advanced one char position, so something was received?

HAL handler should call UART_RxISR_8BIT which in turn calls your callback. Check error bits.

hth

KnarfB

@KnarfB Yes rx_buffer is my global variable that stores the data. I will check tomorrow when I go into work and probe the stm pin, to see what data is coming in.

In the UART_RxISR_8BIT function, the huart->RxCpltCallbacl(huart) gets called, but it happens only once and only goes straight to the return statement, and not the if statement.

JSC4_2-1698592566999.png

My callback function looks like this:

JSC4_1-1698592402713.png

It could be possible that the first character received is garbage (doubt it due to the logic analyser). However, why the callback only happens once is probably a bigger problem.

In terms of error bits, is that taken from the huart instance? For example why debugging the huart in the Live Expressions the ErrorCode is 4.

JSC4_0-1698592805884.png

I believe this is a framing error response, as the UART1_IRQHandler() sets it and has a break point there:

JSC4_0-1698594775388.png

 

KnarfB
Principal III

"huart->RxCpltCallback(huart) is called" Then, USE_HAL_UART_REGISTER_CALLBACKS is still defined. You may regenerate the code to let HAL_UART_RxCpltCallback(huart); be called. The weak default implementation will be replaced by the linker by your function of (exactly) the same name.

The interrupt is only one-shot after HAL_UART_Receive_IT. You have to call that again at the end of your callback.

Single char IRQ based RX will work for lower baud rates, but is a bit of a ressource hog; at least when HAL is used.

Note that there are advanced alternatives.like https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx oder receiving a line until idle or matching char.

hth

KnarfB