cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in the STM32F4xx std periferal library USART module

vech2001
Associate II
Posted on October 29, 2015 at 08:44

Hello. The issue: file stm32f4xx_usart.c, function USART_Init, fractional divider calculation code:

/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
if
((USARTx->CR1 & USART_CR1_OVER8) != 0)
{
tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
}
else
/* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
{
tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
}

It does not take into account that the result of

(((fractionaldivider * 8) + 50) / 100)

or

(((fractionaldivider * 16) + 50) / 100) 

could become equal to, respectively, 8 or It would be required in that case to increment integer divider part while leaving fractional part equal to 0. And, in general, no masking of muldiv result (either by 0x07 or by 0x0f) is required since that result is in the masked range ''by desing'' — except of the case described. Needed something like this:

/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
if
((USARTx->CR1 & USART_CR1_OVER8) != 0)
{
fractionaldivider = ((fractionaldivider * 8) + 50) / 100;
tmpreg += (fractionaldivider < 8) ? fractionaldivider : 0x10;
}
else
/* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
{
tmpreg += ((((fractionaldivider * 16) + 50) / 100));
}

#stm32f4xx-stdperif
0 REPLIES 0