/ * @brief * Configure baudrate (or as close as possible to specified baudrate). * * @note * The setting of a baudrate requires synchronization into the * low frequency domain. If the same register is modified before a previous * update has completed, this function will stall until the previous * synchronization has completed. * * @param[in] leuart * Pointer to LEUART periphe
| 252 | * Baudrate to try to achieve for LEUART. |
| 253 | ******************************************************************************/ |
| 254 | void LEUART_BaudrateSet(LEUART_TypeDef *leuart, |
| 255 | uint32_t refFreq, |
| 256 | uint32_t baudrate) |
| 257 | { |
| 258 | uint32_t clkdiv; |
| 259 | CMU_Clock_TypeDef clock; |
| 260 | |
| 261 | /* Inhibit divide by 0 */ |
| 262 | EFM_ASSERT(baudrate); |
| 263 | |
| 264 | /* |
| 265 | * We want to use integer division to avoid forcing in float division |
| 266 | * utils, and yet keep rounding effect errors to a minimum. |
| 267 | * |
| 268 | * CLKDIV in asynchronous mode is given by: |
| 269 | * |
| 270 | * CLKDIV = 256*(fLEUARTn/br - 1) = ((256*fLEUARTn)/br) - 256 |
| 271 | * |
| 272 | * Normally, with fLEUARTn appr 32768Hz, there is no problem with overflow |
| 273 | * if using 32 bit arithmetic. However, since fLEUARTn may be derived from |
| 274 | * HFCORECLK as well, we must consider overflow when using integer arithmetic. |
| 275 | * |
| 276 | * The basic problem with integer division in the above formula is that |
| 277 | * the dividend (256 * fLEUARTn) may become higher than max 32 bit |
| 278 | * integer. Yet, we want to evaluate dividend first before dividing in |
| 279 | * order to get as small rounding effects as possible. We do not want |
| 280 | * to make too harsh restrictions on max fLEUARTn value either. |
| 281 | * |
| 282 | * Since the last 3 bits of CLKDIV are don't care, we can base our |
| 283 | * integer arithmetic on the below formula |
| 284 | * |
| 285 | * CLKDIV/8 = ((32*fLEUARTn)/br) - 32 |
| 286 | * |
| 287 | * and calculate 1/8 of CLKDIV first. This allows for fLEUARTn |
| 288 | * up to 128MHz without overflowing a 32 bit value! |
| 289 | */ |
| 290 | |
| 291 | /* Get current frequency? */ |
| 292 | if (!refFreq) |
| 293 | { |
| 294 | if (leuart == LEUART0) |
| 295 | { |
| 296 | clock = cmuClock_LEUART0; |
| 297 | } |
| 298 | #if (LEUART_COUNT > 1) |
| 299 | else if (leuart == LEUART1) |
| 300 | { |
| 301 | clock = cmuClock_LEUART1; |
| 302 | } |
| 303 | #endif |
| 304 | else |
| 305 | { |
| 306 | EFM_ASSERT(0); |
| 307 | return; |
| 308 | } |
| 309 | |
| 310 | refFreq = CMU_ClockFreqGet(clock); |
| 311 | } |
no test coverage detected