Skip to content

Instantly share code, notes, and snippets.

@connorworley
Created February 19, 2019 07:04
Show Gist options
  • Save connorworley/3048baaed05e086fd9967f5470df814e to your computer and use it in GitHub Desktop.
Save connorworley/3048baaed05e086fd9967f5470df814e to your computer and use it in GitHub Desktop.
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
use std::ffi::CString;
mod NiFpga {
use std::fmt;
use std::os::raw::c_char;
pub type Session = u32;
#[derive(PartialEq, Eq)]
#[repr(C)]
pub struct Status(i32);
impl Status {
pub const Success: Status = Status(0);
}
impl fmt::Display for Status {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} ({})",
match *self {
Status::Success => "Success",
_ => "Unknown",
},
self.0,
)
}
}
#[link(name = "NiFpga")]
#[link(name = "NiRioSrv")]
#[link(name = "niriodevenum")]
#[link(name = "niriosession")]
extern "C" {
#[link_name = "NiFpgaDll_Open"]
pub fn Open(
bitfile: *const c_char,
signature: *const c_char,
resource: *const c_char,
attribute: u32,
session: *mut Session,
) -> Status;
#[link_name = "NiFpgaDll_Close"]
pub fn Close(session: Session, attribute: u32) -> Status;
#[link_name = "NiFpgaDll_ReadU32"]
pub fn ReadU16(session: Session, indicator: u32, value: *mut u16) -> Status;
}
}
pub trait Register {
type Datatype;
const OFFSET: isize;
const SIZE_IN_BITS: usize;
fn read() -> Self::Datatype;
fn write(data: Self::Datatype);
}
#[no_mangle]
static mut BITFILE_HANDLE: Option<NiFpga::Session> = None;
struct Bitfile {
private_int: i32,
}
impl Bitfile {
#[inline]
pub fn take() -> Option<Self> {
if unsafe { BITFILE_HANDLE.is_some() } {
None
} else {
Some(unsafe { Bitfile::steal() })
}
}
pub unsafe fn steal() -> Self {
assert!(BITFILE_HANDLE.is_none());
let mut handle: NiFpga::Session = 0;
let status: NiFpga::Status = NiFpga::Open(
CString::new("/boot/user.lvbitx").unwrap().as_ptr(),
CString::new("C571384F0C3E586B64ADFE11551DAAD0")
.unwrap()
.as_ptr(),
CString::new("RIO0").unwrap().as_ptr(),
0,
&mut handle as *mut NiFpga::Session,
);
assert!(status == NiFpga::Status::Success);
BITFILE_HANDLE = Some(handle);
Bitfile { private_int: 0 }
}
}
impl Drop for Bitfile {
fn drop(&mut self) {
assert!(
unsafe {
NiFpga::Close(
BITFILE_HANDLE.expect("Bitfile was dropped but BITFILE_HANDLE is None!"),
0,
)
} == NiFpga::Status::Success
);
unsafe {
BITFILE_HANDLE = None;
}
}
}
fn main() {
Bitfile { private_int: 1234 };
let bitfile = Bitfile::take();
debug_assert!(bitfile.is_some());
debug_assert!(Bitfile::take().is_none());
let mut version: u16 = 1234;
let status: NiFpga::Status = unsafe {
NiFpga::ReadU16(
BITFILE_HANDLE.expect("Bitfile in use but BITFILE_HANDLE is None!"),
98314,
&mut version as *mut u16,
)
};
println!("Status: {}", status);
println!("Version: {}", version);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment