# 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> { // 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(&{ if leds.RSL { UnsignedFXP::max_value() } else { UnsignedFXP::min_value() } })?; } } ``` 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.