diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index bbbf97c0..42b3671a 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs @@ -299,7 +299,7 @@ impl<'d, T: Instance> Uart<'d, T, Async> { } } -impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { +impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { fn new_inner( _uart: impl Peripheral

+ 'd, mut tx: PeripheralRef<'d, AnyPin>, @@ -350,23 +350,7 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { pin.pad_ctrl().write(|w| w.set_ie(true)); } - let clk_base = crate::clocks::clk_peri_freq(); - - let baud_rate_div = (8 * clk_base) / config.baudrate; - let mut baud_ibrd = baud_rate_div >> 7; - let mut baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2; - - if baud_ibrd == 0 { - baud_ibrd = 1; - baud_fbrd = 0; - } else if baud_ibrd >= 65535 { - baud_ibrd = 65535; - baud_fbrd = 0; - } - - // Load PL011's baud divisor registers - r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd)); - r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd)); + Self::set_baudrate_inner(config.baudrate); let (pen, eps) = match config.parity { Parity::ParityNone => (false, false), @@ -400,6 +384,35 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { }); } } + + /// sets baudrate on runtime + pub fn set_baudrate(&mut self, baudrate: u32) { + Self::set_baudrate_inner(baudrate); + } + + fn set_baudrate_inner(baudrate: u32) { + let r = T::regs(); + + let clk_base = crate::clocks::clk_peri_freq(); + + let baud_rate_div = (8 * clk_base) / baudrate; + let mut baud_ibrd = baud_rate_div >> 7; + let mut baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2; + + if baud_ibrd == 0 { + baud_ibrd = 1; + baud_fbrd = 0; + } else if baud_ibrd >= 65535 { + baud_ibrd = 65535; + baud_fbrd = 0; + } + + unsafe { + // Load PL011's baud divisor registers + r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd)); + r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd)); + } + } } impl<'d, T: Instance, M: Mode> Uart<'d, T, M> {