1243: RP-PICO UART adding set_baudrate r=Dirbaio a=andres-hurtado-lopez

The following PR attepts to bring fuctionality to allow change od UART baudrate changes during runtime.

Changes where created under `@Dirbaio` supervision and discussed on issue:

[https://github.com/embassy-rs/embassy/issues/1241#issuecomment-1445500175]( https://github.com/embassy-rs/embassy/issues/1241#issuecomment-1445500175)

Co-authored-by: Andres Hurtado Lopez <andresh@cultivate-agri.com>
This commit is contained in:
bors[bot] 2023-02-27 02:26:20 +00:00 committed by GitHub
commit 28b695e7c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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( fn new_inner(
_uart: impl Peripheral<P = T> + 'd, _uart: impl Peripheral<P = T> + 'd,
mut tx: PeripheralRef<'d, AnyPin>, 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)); pin.pad_ctrl().write(|w| w.set_ie(true));
} }
let clk_base = crate::clocks::clk_peri_freq(); Self::set_baudrate_inner(config.baudrate);
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));
let (pen, eps) = match config.parity { let (pen, eps) = match config.parity {
Parity::ParityNone => (false, false), 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> { impl<'d, T: Instance, M: Mode> Uart<'d, T, M> {