2021-10-29 01:48 AM
In this way, error never occurs leading to wrong baudrates.
if (pclk != 0U)
{
/* USARTDIV must be greater than or equal to 0d16 */
usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
{
huart->Instance->BRR = usartdiv;
}
else
{
ret = HAL_ERROR;
}
}
Cast to (uint16_t) should be removed.
Solved! Go to Solution.
2021-11-09 08:40 AM
Hi @Lmoio.1 ,
The cast on (uint16_t) is causing issues in some use cases.
For that, the cast won't be deleted but modified to be (uint32_t) instead of (uint16_t).
- usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
+ usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
When your question is answered, please close this topic by choosing Select as Best. So that more Community members can benefit from this discussion.
Imen
2021-11-04 10:02 AM
Hello @Lmoio.1 ,
Please clarify the case where the uint16_t cast is a problem!
BRR register in UART IP is only 16 bit wide.
If clock, baudrate and prescaler values are correct, casting the value computed by calling UART_DIV_SAMPLING16 or UART_DIV_SAMPLING8 macros should not affect the result.
If cast alters the result (result > 0xFFFF), then the combination is not possible anyway (next check against UART_BRR_MAX will fail).
Can you please provide your clock/baudrate/prescaler value, and indicate how the BRR setting is wrongly computed due to the uint16 cast ?
Imen
2021-11-05 01:23 AM
Hi @Imen DAHMEN ,
this was my configuration:
Clock 170MHz,
Prescaler UART_PRESCALER_DIV1 so 0,
Oversampling UART_OVERSAMPLING_16,
Baudrate expected 2400.
The BRR register for oversampling 16 is computed as follows: BRR = (Clock/prescaler)/baudrate rounded up. So (170000000/1)/2400 = 70834.
Obviously 70834 is greater than 0xFFFF and the check should fail, going in the return HAL_ERROR; branch.
However with the cast uint16_t, 70834 becomes 5298 that is lower than 0xFFFF, thus the initialization of uart completes, without giving any error.
The problem was discovered by looking at the signals with an oscilloscope.
Lidia
2021-11-07 04:37 AM
> If cast alters the result (result > 0xFFFF), then the combination is not possible anyway (next check against UART_BRR_MAX will fail).
That's the thing - the cast already limits the usartdiv value to a max of 0xFFFF and the test against the UART_BRR_MAX will never fail. Lidia is right on this! Also the line 3160 has the same problem and at line 3118 the cast is useless because it casts to the same type of usartdiv variable.
2021-11-09 08:40 AM
Hi @Lmoio.1 ,
The cast on (uint16_t) is causing issues in some use cases.
For that, the cast won't be deleted but modified to be (uint32_t) instead of (uint16_t).
- usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
+ usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
When your question is answered, please close this topic by choosing Select as Best. So that more Community members can benefit from this discussion.
Imen
2021-11-09 08:43 AM
Thank you!
Lidia
2021-11-09 08:45 AM
You are welcome :)