ni_fpga_interface/session/
mod.rs1mod data_interfaces;
4pub mod fifo_control;
5use std::sync::atomic::AtomicBool;
6use std::sync::atomic::Ordering;
7use std::sync::Arc;
8
9use crate::error::{to_fpga_result, FPGAError};
10use crate::nifpga_sys::*;
11pub use data_interfaces::*;
12
13static CONTEXT_ACTIVE: AtomicBool = AtomicBool::new(false);
14
15pub struct NiFpgaContext();
21
22impl NiFpgaContext {
23 pub fn new() -> Result<Arc<Self>, FPGAError> {
28 if CONTEXT_ACTIVE
30 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
31 .is_err()
32 {
33 return Err(FPGAError::ContextAlreadyActive);
34 }
35
36 let status = unsafe { NiFpga_Initialize() };
37 to_fpga_result(Arc::new(Self {}), status)
38 }
40}
41
42impl Drop for NiFpgaContext {
43 fn drop(&mut self) {
44 unsafe {
45 NiFpga_Finalize();
46 }
47 CONTEXT_ACTIVE.store(false, std::sync::atomic::Ordering::SeqCst);
48 }
49}
50
51pub struct SessionOptions {
53 pub reset_on_close: bool,
55 pub run_on_open: bool,
57}
58
59impl SessionOptions {
60 fn open_attribute(&self) -> u32 {
61 let mut attribute = 0;
62 if !self.run_on_open {
63 attribute |= 1;
64 }
65 attribute
66 }
67
68 fn close_attribute(&self) -> u32 {
69 let mut attribute = 0;
70 if !self.reset_on_close {
71 attribute |= 1;
72 }
73 attribute
74 }
75}
76
77impl Default for SessionOptions {
78 fn default() -> Self {
79 Self {
80 reset_on_close: true,
81 run_on_open: true,
82 }
83 }
84}
85
86pub struct Session {
87 pub handle: SessionHandle,
88 close_attribute: u32,
89 _context: Arc<NiFpgaContext>,
90}
91
92impl Session {
93 pub fn new(
116 context: &Arc<NiFpgaContext>,
117 bitfile: &str,
118 signature: &str,
119 resource: &str,
120 options: &SessionOptions,
121 ) -> Result<Self, crate::error::FPGAError> {
122 let mut handle: SessionHandle = 0;
123 let bitfile = std::ffi::CString::new(bitfile).unwrap();
124 let signature = std::ffi::CString::new(signature).unwrap();
125 let resource = std::ffi::CString::new(resource).unwrap();
126 let result = unsafe {
127 NiFpga_Open(
128 bitfile.as_ptr(),
129 signature.as_ptr(),
130 resource.as_ptr(),
131 options.open_attribute(),
132 &mut handle,
133 )
134 };
135 to_fpga_result(
136 Self {
137 handle,
138 _context: context.clone(),
139 close_attribute: options.close_attribute(),
140 },
141 result,
142 )
143 }
144
145 pub fn set_options(&mut self, options: &SessionOptions) {
163 self.close_attribute = options.close_attribute();
164 }
165
166 pub fn reset(&mut self) -> Result<(), crate::error::FPGAError> {
168 let result = unsafe { NiFpga_Reset(self.handle) };
169
170 to_fpga_result((), result)
171 }
172
173 pub fn run(&mut self, wait_until_done: bool) -> Result<(), crate::error::FPGAError> {
176 let attributes = if wait_until_done { 1 } else { 0 };
177
178 let result = unsafe { NiFpga_Run(self.handle, attributes) };
179
180 to_fpga_result((), result)
181 }
182
183 pub fn abort(&mut self) -> Result<(), crate::error::FPGAError> {
185 let result = unsafe { NiFpga_Abort(self.handle) };
186
187 to_fpga_result((), result)
188 }
189
190 pub fn download(&mut self) -> Result<(), crate::error::FPGAError> {
192 let result = unsafe { NiFpga_Download(self.handle) };
193
194 to_fpga_result((), result)
195 }
196
197 pub fn close(self) -> Result<(), crate::error::FPGAError> {
199 let result = unsafe { NiFpga_Close(self.handle, self.close_attribute) };
200
201 to_fpga_result((), result)
202 }
203}
204
205impl Drop for Session {
206 fn drop(&mut self) {
207 unsafe {
208 NiFpga_Close(self.handle, self.close_attribute);
209 }
210 }
211}
212
213#[cfg(test)]
214mod tests {
215
216 #[test]
217 fn test_session_options_default() {
218 let options = super::SessionOptions::default();
219 assert_eq!(options.run_on_open, true);
220 assert_eq!(options.reset_on_close, true);
221 }
222
223 #[test]
224 fn test_session_options_get_open_attribute_run() {
225 let mut options = super::SessionOptions::default();
226 options.run_on_open = true;
227 assert_eq!(options.open_attribute(), 0);
228 }
229
230 #[test]
231 fn test_session_options_get_open_attribute_no_run() {
232 let mut options = super::SessionOptions::default();
233 options.run_on_open = false;
234 assert_eq!(options.open_attribute(), 1);
235 }
236
237 #[test]
238 fn test_session_options_get_close_attribute_reset() {
239 let mut options = super::SessionOptions::default();
240 options.reset_on_close = true;
241 assert_eq!(options.close_attribute(), 0);
242 }
243
244 #[test]
245 fn test_session_options_get_close_attribute_no_reset() {
246 let mut options = super::SessionOptions::default();
247 options.reset_on_close = false;
248 assert_eq!(options.close_attribute(), 1);
249 }
250}