Created
February 19, 2019 07:04
-
-
Save connorworley/3048baaed05e086fd9967f5470df814e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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