rustborrow-checkerrp2040

RP2040, reconciling ownership and glitchy hardware


I have some Rust code for an RP2040. It communicates over UART, but I'm dealing with some sorta glitchy components; seems like after a few milliseconds of inactivity they need a few microseconds of activity on the tx line before they've warmed up and actually accept tx, which means my UART communications (past a limited baud) get garbled.

I'd like to try toggling the tx line shortly before the UART transmission, to warm up the components, but I pass ownership of the pin to the UART, and I don't know how to get it back or bypass it or circumvent the problem.

Here's sorta what I'd like to do, but of course the borrow checker doesn't like it, as commented:

let mut gpio0 = pins.gpio0;
let mut gpio1 = pins.gpio1;
let uart_pins_0 = (
    gpio0.into_function(), // `gpio0` moved due to this method call
    gpio1.into_function(),
);
let mut uart0 = UartPeripheral::new(peripherals.UART0, uart_pins_0, &mut peripherals.RESETS)
    .enable(
        UartConfig::new(baud.Hz(), DataBits::Eight, None, StopBits::One),
        clocks.peripheral_clock.freq(),
    ).unwrap();
gpio0.into_push_pull_output().set_high().unwrap(); // use of moved value: `gpio0`
delay.delay_us(10);
gpio0.into_push_pull_output().set_low().unwrap();
delay.delay_us(10);
uart0.write_str("test\n").unwrap();

How do I accommodate my buggy components while working with the borrow checker?


Solution

  • UartPeripherals provides you a free() method that can give you the pins back.

    In practice, this looks something like:

    let (d, mut p) = uart1.free();
    let mut g = p.0.into_push_pull_output();
    g.set_low().unwrap();
    delay.delay_us(3);
    g.set_high().unwrap();
    p.0 = g.into_function();
    uart1 = UartPeripheral::new(d, p, &mut peripherals.RESETS)
    .enable(
        UartConfig::new(baud.Hz(), DataBits::Eight, None, StopBits::One),
        clocks.peripheral_clock.freq(),
    ).unwrap();
    

    Note that, according to testing, recreating the uart clears the rx queue.