MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / LEUART_BaudrateCalc

Function LEUART_BaudrateCalc

bsp/efm32/Libraries/emlib/src/em_leuart.c:127–189  ·  view source on GitHub ↗

/ * @brief * Calculate baudrate for LEUART given reference frequency and clock division. * * @details * This function returns the baudrate that a LEUART module will use if * configured with the given frequency and clock divisor. Notice that * this function will not use actual HW configuration. It can be used * to determinate if a given configuration is sufficiently accurate for th

Source from the content-addressed store, hash-verified

125 * Baudrate with given settings.
126 ******************************************************************************/
127uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv)
128{
129 uint32_t divisor;
130 uint32_t remainder;
131 uint32_t quotient;
132 uint32_t br;
133
134 /* Mask out unused bits */
135 clkdiv &= _LEUART_CLKDIV_MASK;
136
137 /* We want to use integer division to avoid forcing in float division */
138 /* utils, and yet keep rounding effect errors to a minimum. */
139
140 /*
141 * Baudrate is given by:
142 *
143 * br = fLEUARTn/(1 + (CLKDIV / 256))
144 *
145 * which can be rewritten to
146 *
147 * br = (256 * fLEUARTn)/(256 + CLKDIV)
148 *
149 * Normally, with fLEUARTn appr 32768Hz, there is no problem with overflow
150 * if using 32 bit arithmetic. However, since fLEUARTn may be derived from
151 * HFCORECLK as well, we must consider overflow when using integer arithmetic.
152 */
153
154 /*
155 * The basic problem with integer division in the above formula is that
156 * the dividend (256 * fLEUARTn) may become higher than max 32 bit
157 * integer. Yet we want to evaluate dividend first before dividing in
158 * order to get as small rounding effects as possible. We do not want
159 * to make too harsh restrictions on max fLEUARTn value either.
160 *
161 * For division a/b, we can write
162 *
163 * a = qb + r
164 *
165 * where q is the quotient and r is the remainder, both integers.
166 *
167 * The orignal baudrate formula can be rewritten as
168 *
169 * br = 256a / b = 256(qb + r)/b = 256q + 256r/b
170 *
171 * where a is 'refFreq' and b is 'divisor', referring to variable names.
172 */
173
174 divisor = 256 + clkdiv;
175
176 quotient = refFreq / divisor;
177 remainder = refFreq % divisor;
178
179 /* Since divisor >= 256, the below cannot exceed max 32 bit value. */
180 br = 256 * quotient;
181
182 /*
183 * Remainder < (256 + clkdiv), which means dividend (256 * remainder) worst case is
184 * 256*(256 + 0x7ff8) = 0x80F800.

Callers 1

LEUART_BaudrateGetFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected