cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Cube HAL UART. Is it a bug or am I missing something?

rublag-ns
Associate
Posted on November 06, 2015 at 04:33

I am using interrupt based UART IO (no DMA).

HAL_UART_Transmit_IT

function sets

EIE

bit in

CR3

register. According to STM32F407 datasheet (and real behaviour), this generates interrupt only in multi buffer mode (when

DMAR

bit is set).

EIE

enables interrupt generation for frame error (

FE

), overrun error (

ORE

), noise error (

NE

). This error, as I understand, only for receiving.

Part of

HAL_UART_IRQHandler

function:

tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);

tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);

/* UART Over-Run interrupt occurred ----------------------------------------*/

if

((tmp1 != RESET) && (tmp2 != RESET))

{

__HAL_UART_CLEAR_OREFLAG(huart);

huart->ErrorCode |= HAL_UART_ERROR_ORE;

}

if

(huart->ErrorCode != HAL_UART_ERROR_NONE)

{

/* Set the UART state ready to be able to start again the process */

huart->State = HAL_UART_STATE_READY;

HAL_UART_ErrorCallback(huart);

}

HAL_UART_IRQHandler

checks for each error. If error occurred and

EIE

bit is set, it resets UART state, but doesn't reset interrupt enabling bits, so

TXE

interrupt will be always generated, but

UART_Transmit_IT

function treats state

HAL_UART_STATE_READY

as invalid and doesn't do anything. Infinite loop.

Part of

UART_Transmit_IT

function:

static

HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)

{

uint16_t* tmp;

uint32_t tmp1 = 0;

tmp1 = huart->State;

if

((tmp1 == HAL_UART_STATE_BUSY_TX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX))

{

}

else

{

return

HAL_BUSY;

}

}

Is it a bug in Cube HAL?

#stm32 #stm32f4 #hal #hal #uart #usart #interrupts #bug #stm32f4

4 REPLIES 4
Posted on November 09, 2015 at 14:13

Hi ns.rublag,

I understand the bug, it will be reported to development team.

-Shahrzad-

valtin
Associate II
Posted on January 17, 2016 at 03:38

This BUG is also true for receiving data.

I have a BT module with a ''connected'' GPIO. So I enable the USART after this pin goes high. This takes some time and the PC does not know about it, so data is send as soon as the BT connection is established. This results in overrun errors and that triggers the bug...

My workaround used the UART_Error_Callback function:

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)

{

    if (huart->ErrorCode == HAL_UART_ERROR_ORE){

        // remove the error condition

        huart->ErrorCode = HAL_UART_ERROR_NONE;

        // set the correct state, so that the UART_RX_IT works correctly

        huart->State = HAL_UART_STATE_BUSY_RX;

    }

}

but a general solution is probably a lot more difficult ...
Posted on January 25, 2016 at 16:42

Hi all,

This bug is already known.

,

Regarding error detection, maybe another thing that could be reminded: when errors are detected, state is updated in order to allow further API calls (not to remain blocked in some cases, with default (empty) error handling). In HAL_UART_IRQHandler(), Error flag is cleared in ICR register, and ErrorCode is updated to keep error type for user. Then, HAL_UART_ErrorCallback() is called. In HAL, this function is defined with “Weak� attribute, with an empty body.

Error handling procedure has to be defined and implemented in a new HAL_UART_ErrorCallback() function, in user code, that will supersede weak one.

-Shahrzad-

john gassel
Associate III
Posted on June 20, 2017 at 21:59

Is there any update from ST about this?  Will it be fixed in a future version of the HAL?