pub(crate) struct BaudRegs {
pub(crate) ucbr: u16,
pub(crate) ucbrf: u8,
pub(crate) ucbrs: u8,
pub(crate) oversampling: bool,
}
pub(crate) const UCBRS_TABLE: [(u32, u8); 36] = [
(0, 0x00),
(529, 0x01),
(715, 0x02),
(835, 0x04),
(1001, 0x08),
(1252, 0x10),
(1430, 0x20),
(1670, 0x11),
(2147, 0x21),
(2224, 0x22),
(2503, 0x44),
(3000, 0x25),
(3335, 0x49),
(3575, 0x4A),
(3753, 0x52),
(4003, 0x92),
(4286, 0x53),
(4378, 0x55),
(5002, 0xAA),
(5715, 0x6B),
(6003, 0xAD),
(6254, 0xB5),
(6432, 0xB6),
(6667, 0xD6),
(7001, 0xB7),
(7147, 0xBB),
(7503, 0xDD),
(7861, 0xED),
(8004, 0xEE),
(8333, 0xBF),
(8464, 0xDF),
(8572, 0xEF),
(8751, 0xF7),
(9004, 0xFB),
(9170, 0xFD),
(9288, 0xFE),
];
pub(crate) fn ucbrs_lookup(frac_x10000: u32) -> u8 {
let mut result = 0u8;
let mut i = 0;
while i < UCBRS_TABLE.len() {
if UCBRS_TABLE[i].0 <= frac_x10000 {
result = UCBRS_TABLE[i].1;
} else {
break;
}
i += 1;
}
result
}
pub(crate) fn compute_baud(clock_freq: u32, baud: u32) -> BaudRegs {
let n_int = clock_freq / baud; let frac_x10000 = (((clock_freq - n_int * baud) as u64) * 10_000 / baud as u64) as u32;
let ucbrs = ucbrs_lookup(frac_x10000);
if n_int >= 16 {
let ucbr = clock_freq / (16 * baud);
let ucbrf = (n_int - 16 * ucbr) as u8; BaudRegs {
ucbr: ucbr as u16,
ucbrf,
ucbrs,
oversampling: true,
}
} else {
BaudRegs {
ucbr: n_int as u16,
ucbrf: 0,
ucbrs,
oversampling: false,
}
}
}