# lvbitfile2rust
[![crates.io](https://img.shields.io/crates/v/lvbitfile2rust.svg)](https://crates.io/crates/lvbitfile2rust)
[![docs.rs](https://docs.rs/lvbitfile2rust/badge.svg)](https://docs.rs/lvbitfile2rust)
[![CI](https://github.com/first-rust-competition/lvbitfile2rust/workflows/CI/badge.svg)](https://github.com/first-rust-competition/lvbitfile2rust/actions?query=workflow%3ACI)

lvbitfile2rust generates static register maps from lvbitx files.

## Invoking from the command line
```sh
cargo install lvbitfile2rust
lvbitfile2rust-cli /boot/user.lvbitx | rustfmt > rio.rs
```

## Invoking as a macro
```rust
mod rio {
    use lvbitfile2rust_macros::lvbitfile2rust;
    lvbitfile2rust!("/boot/user.lvbitx");
}
```

## Generated code
lvbitfile2rust generates code with a similar interface to code generated by [svd2rust](https://github.com/rust-embedded/svd2rust). The generated code contains a struct named `Peripherals` with an associated function named `take`. Calling `take` will attempt to open an FPGA session and return a `Peripherals` instance. The `Peripherals` instance contains fields for each register described by the input bitfile. These fields contain instances of structs corresponding to each register, with `read` and possibly `write` methods. In practice, the interface is rather straightforward to use:
```rust
use ni_fpga::fxp::UnsignedFXP;

mod rio {
    use lvbitfile2rust_macros::lvbitfile2rust;
    lvbitfile2rust!("/boot/user.lvbitx");
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Turn PWM on if the RSL is on!
    // My scope tells me the RSL blinks at 5Hz in teleop mode!
    let peripherals = rio::Peripherals::take("RIO0")?;
    loop {
        let leds = peripherals.LEDs.read()?;
        peripherals.PWM_Hdr0.write(&UnsignedFXP::<12, 12>::from_raw({
            if leds.RSL {
                (1 << 12) - 1
            } else {
                0
            }
        })?)?;
    }
}
```
Generated code will depend on [ni-fpga](https://github.com/first-rust-competition/ni-fpga-rs) and ni-fpga-macros if the input bitfile uses Clusters or Enums.
