diff --git a/va108xx-hal/CHANGELOG.md b/va108xx-hal/CHANGELOG.md index d2bff1c..30161ef 100644 --- a/va108xx-hal/CHANGELOG.md +++ b/va108xx-hal/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Replace I2C `i2ca`, `i2cb` constructors by `new` constructor. Update constructor to fail on invalid fast I2C speed system clock values - Renamed `gpio::pins` to `gpio::pin` and `gpio::dynpins` to `gpio::dynpin` +- Simplify UART clock divider calculations and remove `libm` dependency consequently ## [v0.6.0] 2024-06-16 diff --git a/va108xx-hal/Cargo.toml b/va108xx-hal/Cargo.toml index 4941a41..2a10125 100644 --- a/va108xx-hal/Cargo.toml +++ b/va108xx-hal/Cargo.toml @@ -16,7 +16,6 @@ cortex-m-rt = "0.7" nb = "1" paste = "1" embedded-hal-nb = "1" -libm = "0.2" embedded-io = "0.6" fugit = "0.3" typenum = "1" diff --git a/va108xx-hal/src/uart.rs b/va108xx-hal/src/uart.rs index 1073e75..4b35fa1 100644 --- a/va108xx-hal/src/uart.rs +++ b/va108xx-hal/src/uart.rs @@ -7,7 +7,6 @@ use core::{marker::PhantomData, ops::Deref}; use embedded_hal_nb::serial::Read; use fugit::RateExtU32; -use libm::floorf; pub use crate::IrqCfg; use crate::{ @@ -365,12 +364,19 @@ impl UartBase { false => 16, true => 8, }; + + // This is the calculation: (64.0 * (x - integer_part as f32) + 0.5) as u32 without floating + // point calculations. + let frac = ((sys_clk.raw() % (config.baudrate.raw() * 16)) * 64 + + (config.baudrate.raw() * 8)) + / (config.baudrate.raw() * 16); + // Calculations here are derived from chapter 4.8.5 (p.79) of the datasheet. let x = sys_clk.raw() as f32 / (config.baudrate.raw() * baud_multiplier) as f32; - let integer_part = floorf(x) as u32; - let frac = floorf(64.0 * (x - integer_part as f32) + 0.5) as u32; - self.uart - .clkscale() - .write(|w| unsafe { w.bits(integer_part * 64 + frac) }); + let integer_part = x as u32; + self.uart.clkscale().write(|w| unsafe { + w.frac().bits(frac as u8); + w.int().bits(integer_part) + }); let (paren, pareven) = match config.parity { Parity::None => (false, false),