Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
Diff: targets/hal/TARGET_NXP/TARGET_LPC23XX/serial_api.c
- Revision:
- 51:7838415c99e7
- Parent:
- 20:4263a77256ae
- Child:
- 140:ca60b7a31055
--- a/targets/hal/TARGET_NXP/TARGET_LPC23XX/serial_api.c Tue Nov 26 15:30:05 2013 +0000 +++ b/targets/hal/TARGET_NXP/TARGET_LPC23XX/serial_api.c Mon Dec 02 10:00:04 2013 +0000 @@ -156,22 +156,47 @@ uint16_t dlv; uint8_t mv, dav; if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder - float err_best = (float) baudrate; - uint16_t dlmax = DL; - for ( dlv = (dlmax/2); (dlv <= dlmax) && !hit; dlv++) { - for ( mv = 1; mv <= 15; mv++) { - for ( dav = 1; dav < mv; dav++) { - float ratio = 1.0f + ((float) dav / (float) mv); - float calcbaud = (float)PCLK / (16.0f * (float) dlv * ratio); - float err = fabs(((float) baudrate - calcbaud) / (float) baudrate); - if (err < err_best) { - DL = dlv; - DivAddVal = dav; - MulVal = mv; - err_best = err; - if (err < 0.001f) { - hit = 1; - } + int err_best = baudrate, b; + for (mv = 1; mv < 16 && !hit; mv++) + { + for (dav = 0; dav < mv; dav++) + { + // baudrate = PCLK / (16 * dlv * (1 + (DivAdd / Mul)) + // solving for dlv, we get dlv = mul * PCLK / (16 * baudrate * (divadd + mul)) + // mul has 4 bits, PCLK has 27 so we have 1 bit headroom which can be used for rounding + // for many values of mul and PCLK we have 2 or more bits of headroom which can be used to improve precision + // note: X / 32 doesn't round correctly. Instead, we use ((X / 16) + 1) / 2 for correct rounding + + if ((mv * PCLK * 2) & 0x80000000) // 1 bit headroom + dlv = ((((2 * mv * PCLK) / (baudrate * (dav + mv))) / 16) + 1) / 2; + else // 2 bits headroom, use more precision + dlv = ((((4 * mv * PCLK) / (baudrate * (dav + mv))) / 32) + 1) / 2; + + // datasheet says if DLL==DLM==0, then 1 is used instead since divide by zero is ungood + if (dlv == 0) + dlv = 1; + + // datasheet says if dav > 0 then DL must be >= 2 + if ((dav > 0) && (dlv < 2)) + dlv = 2; + + // integer rearrangement of the baudrate equation (with rounding) + b = ((PCLK * mv / (dlv * (dav + mv) * 8)) + 1) / 2; + + // check to see how we went + b = abs(b - baudrate); + if (b < err_best) + { + err_best = b; + + DL = dlv; + MulVal = mv; + DivAddVal = dav; + + if (b == baudrate) + { + hit = 1; + break; } } }