cancel
Showing results for 
Search instead for 
Did you mean: 

Bug: UART BRR calculate error when oversampling by 8. And Poor algorithm

zh_jianjun
Associate II
Posted on April 25, 2015 at 04:52

This error lasts a long long time, and maybe still exists other version of stdperiph or Cube.

In STM32Cube_FW_F4_V1.5.0 the error is in this line of stm32f4xx_hal_uart.h:

#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_)             ((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4)|(UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) &

0x0F

))

should be:

#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_)             ((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4)|(UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) &

0x07

))

Can I complain about the too complex algorithm?

When oversampling by 16, the divide rate is PCLK/(BAUD*16). We have 4 bit fraction in BRR register, then:

BRR = ((PCLK/(BAUD*16))<<4 = PCLK/BAUD. Isn't that simple?

In most case when PCLK/BAUD>100, you can ignore the truncation error.

Or you can use use the rounding to be more accurate: BRR = (PCLK+BAUD/2)/BAUD

Now we can replace UART_BRR_SAMPLING16 macro with:

#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_)     (((_PCLK_)+(_BAUD_)/2)/_BAUD_)

When oversampling by 8, the divide rate is PCLK/(BAUD*8).

In manual: ''When OVER8=1, the DIV_Fraction3 bit is not considered and must be kept cleared.'' means BRR register has 3 bit fraction, and 1 bit blank.

Then BBR=(PCLK/(BAUD*8))<<3 = PCLK/BAUD, same result except that one blank bit is inserted in bit3.

Following inline function can replace the UART_BRR_SAMPLING8 Macro:

__INLINE static uint16_t UART_BRR_SAMPLING8(uint32_t _PCLK_, uint32_t _BAUD_)

{

    uint16_t Div = (_PCLK_ + _BAUD_/2)/_BAUD_;    //result in 3 bit fraction, 15 bit Mantissa

    //When OVER8=1, the DIV_Fraction3 bit is not considered and must be kept cleared.

    uint16_t DIV_Mantissa = (Div & ~0x7)<<1;

    uint16_t DIV_Fraction = Div & 0x07    

    return (DIV_Mantissa | DIV_Fraction);

}

Variable DIV_Mantissa and DIV_Fraction are used for more clear.

my git commit:

https://github.com/skywolf/STM32Cube_FW_F4_BugFix/commit/ccdb3219c88559b7652d00859f5a82087af4afeb

https://git.oschina.net/dingtu/STM32Cube_FW_F4_BugFix/commit/ccdb3219c88559b7652d00859f5a82087af4afeb
0 REPLIES 0