Improve UART CLK calculation #12

Merged
muellerr merged 3 commits from improve-uart-clk-calc into main 2024-07-04 18:33:10 +02:00
3 changed files with 13 additions and 7 deletions

View File

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Replace I2C `i2ca`, `i2cb` constructors by `new` constructor. Update constructor - Replace I2C `i2ca`, `i2cb` constructors by `new` constructor. Update constructor
to fail on invalid fast I2C speed system clock values to fail on invalid fast I2C speed system clock values
- Renamed `gpio::pins` to `gpio::pin` and `gpio::dynpins` to `gpio::dynpin` - 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 ## [v0.6.0] 2024-06-16

View File

@ -16,7 +16,6 @@ cortex-m-rt = "0.7"
nb = "1" nb = "1"
paste = "1" paste = "1"
embedded-hal-nb = "1" embedded-hal-nb = "1"
libm = "0.2"
embedded-io = "0.6" embedded-io = "0.6"
fugit = "0.3" fugit = "0.3"
typenum = "1" typenum = "1"

View File

@ -7,7 +7,6 @@
use core::{marker::PhantomData, ops::Deref}; use core::{marker::PhantomData, ops::Deref};
use embedded_hal_nb::serial::Read; use embedded_hal_nb::serial::Read;
use fugit::RateExtU32; use fugit::RateExtU32;
use libm::floorf;
pub use crate::IrqCfg; pub use crate::IrqCfg;
use crate::{ use crate::{
@ -365,12 +364,19 @@ impl<UART: Instance> UartBase<UART> {
false => 16, false => 16,
true => 8, 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 x = sys_clk.raw() as f32 / (config.baudrate.raw() * baud_multiplier) as f32;
let integer_part = floorf(x) as u32; let integer_part = x as u32;
let frac = floorf(64.0 * (x - integer_part as f32) + 0.5) as u32; self.uart.clkscale().write(|w| unsafe {
self.uart w.frac().bits(frac as u8);
.clkscale() w.int().bits(integer_part)
.write(|w| unsafe { w.bits(integer_part * 64 + frac) }); });
let (paren, pareven) = match config.parity { let (paren, pareven) = match config.parity {
Parity::None => (false, false), Parity::None => (false, false),