ni_fpga_interface/session/
data_interfaces.rs1use crate::error::{to_fpga_result, Result};
9use crate::nifpga_sys::*;
10use crate::session::Session;
11use crate::types::FpgaBool;
12use libc::size_t;
13use paste::paste;
14use std::time::Duration;
15
16pub trait NativeFpgaType: Copy {}
18
19pub type RegisterAddress = u32;
20
21pub trait RegisterInterface<T: Default + Copy> {
22 fn read(&self, address: RegisterAddress) -> Result<T>;
23 fn write(&self, address: RegisterAddress, data: T) -> Result<()>;
24 fn read_array<const N: usize>(&self, address: RegisterAddress) -> Result<[T; N]> {
25 let mut array: [T; N] = [T::default(); N];
26 self.read_array_mut(address, &mut array)?;
27 Ok(array)
28 }
29 fn read_array_mut<const N: usize>(
30 &self,
31 address: RegisterAddress,
32 array: &mut [T; N],
33 ) -> Result<()>;
34 fn write_array<const N: usize>(&self, address: RegisterAddress, data: &[T; N]) -> Result<()>;
35}
36
37pub struct FifoReadRegion<'session, 'data, T: NativeFpgaType> {
43 session: &'session Session,
44 fifo: FifoAddress,
45 pub elements: &'data [T],
46}
47
48impl<'s, 'd, T: NativeFpgaType> Drop for FifoReadRegion<'s, 'd, T> {
49 fn drop(&mut self) {
50 let _ = self
52 .session
53 .release_fifo_elements(self.fifo, self.elements.len());
54 }
55}
56
57pub struct FifoWriteRegion<'session, 'data, T: NativeFpgaType> {
63 session: &'session Session,
64 fifo: FifoAddress,
65 pub elements: &'data mut [T],
66}
67
68impl<'s, 'd, T: NativeFpgaType> Drop for FifoWriteRegion<'s, 'd, T> {
69 fn drop(&mut self) {
70 let _ = self
72 .session
73 .release_fifo_elements(self.fifo, self.elements.len());
74 }
75}
76
77pub trait FifoInterface<T: NativeFpgaType> {
78 fn read_fifo(
82 &self,
83 fifo: FifoAddress,
84 buffer: &mut [T],
85 timeout: Option<Duration>,
86 ) -> Result<usize>;
87
88 fn write_fifo(&self, fifo: FifoAddress, data: &[T], timeout: Option<Duration>)
92 -> Result<usize>;
93
94 fn zero_copy_read(
96 &self,
97 fifo: FifoAddress,
98 elements: usize,
99 timeout: Option<Duration>,
100 ) -> Result<(FifoReadRegion<T>, usize)>;
101
102 fn zero_copy_write(
104 &self,
105 fifo: FifoAddress,
106 elements: usize,
107 timeout: Option<Duration>,
108 ) -> Result<(FifoWriteRegion<T>, usize)>;
109}
110
111macro_rules! impl_type_session_interface {
113 ($rust_type:ty, $fpga_type:literal) => {
114
115
116 paste! {
117 impl NativeFpgaType for $rust_type {}
118
119 impl RegisterInterface<$rust_type> for Session {
120 fn read(&self, address: RegisterAddress) -> Result<$rust_type> {
121 let mut value: $rust_type = $rust_type::default();
122 let return_code = unsafe {[< NiFpga_Read $fpga_type >](self.handle, address, &mut value)};
123 to_fpga_result(value, return_code)
124 }
125 fn write(&self, address: RegisterAddress, value: $rust_type) -> Result<()> {
126 let return_code = unsafe {[< NiFpga_Write $fpga_type >](self.handle, address, value)};
127 to_fpga_result((), return_code)
128 }
129 fn read_array_mut<const N:usize>(&self, address: RegisterAddress, array: &mut [$rust_type; N]) -> Result<()> {
130 let return_code = unsafe {[< NiFpga_ReadArray $fpga_type >](self.handle, address, array.as_mut_ptr(), N)};
131 to_fpga_result((), return_code)
132 }
133 fn write_array<const N:usize>(&self, address: RegisterAddress, value: &[$rust_type;N]) -> Result<()> {
134 let return_code = unsafe {[< NiFpga_WriteArray $fpga_type >](self.handle, address, value.as_ptr(), N)};
135 to_fpga_result((), return_code)
136 }
137 }
138
139 impl FifoInterface<$rust_type> for Session {
140 fn read_fifo(&self, fifo: u32, data: &mut [$rust_type], timeout: Option<Duration>) -> Result< usize> {
141 let mut elements_remaining: size_t = 0;
142 let return_code = unsafe {[< NiFpga_ReadFifo $fpga_type >](self.handle, fifo, data.as_mut_ptr(), data.len(), timeout.into(), &mut elements_remaining)};
143 to_fpga_result(elements_remaining, return_code)
144 }
145 fn write_fifo(&self, fifo: u32, data: &[$rust_type], timeout: Option<Duration>) -> Result<usize> {
146 let mut elements_remaining: size_t = 0;
147 let return_code = unsafe {[< NiFpga_WriteFifo $fpga_type >](self.handle, fifo, data.as_ptr(), data.len(), timeout.into(), &mut elements_remaining)};
148 to_fpga_result(elements_remaining, return_code)
149 }
150 fn zero_copy_read(&self, fifo: u32, elements: usize, timeout: Option<Duration>) -> Result<(FifoReadRegion<$rust_type>, usize)> {
151 let mut elements_acquired: size_t = 0;
152 let mut elements_remaining: size_t = 0;
153 let mut data: *const $rust_type = std::ptr::null();
154 let return_code = unsafe {[< NiFpga_AcquireFifoReadElements $fpga_type >](self.handle, fifo, &mut data, elements, timeout.into(), &mut elements_acquired, &mut elements_remaining)};
155 let read_region = FifoReadRegion{session: self, fifo, elements: unsafe {std::slice::from_raw_parts(data, elements_acquired)}};
156 to_fpga_result((read_region, elements_remaining), return_code)
157 }
158 fn zero_copy_write(&self, fifo: u32, elements: usize, timeout: Option<Duration>) -> Result<(FifoWriteRegion<$rust_type>, usize)> {
159 let mut elements_acquired: size_t = 0;
160 let mut elements_remaining: size_t = 0;
161 let mut data: *mut $rust_type = std::ptr::null_mut();
162 let return_code = unsafe {[< NiFpga_AcquireFifoWriteElements $fpga_type >](self.handle, fifo, &mut data, elements, timeout.into(), &mut elements_acquired, &mut elements_remaining)};
163 let write_region = FifoWriteRegion{session: self, fifo, elements: unsafe {std::slice::from_raw_parts_mut(data, elements_acquired)}};
164 to_fpga_result((write_region, elements_remaining), return_code)
165 }
166 }
167 }
168 }
169}
170
171impl_type_session_interface!(u8, "U8");
172impl_type_session_interface!(u16, "U16");
173impl_type_session_interface!(u32, "U32");
174impl_type_session_interface!(u64, "U64");
175impl_type_session_interface!(i8, "I8");
176impl_type_session_interface!(i16, "I16");
177impl_type_session_interface!(i32, "I32");
178impl_type_session_interface!(i64, "I64");
179impl_type_session_interface!(f32, "Sgl");
180impl_type_session_interface!(f64, "Dbl");
181impl_type_session_interface!(FpgaBool, "Bool");