1extern crate memmap;
13
14use std::error::Error;
15use std::fs::File;
16use std::fmt;
17
18use memmap::{Mmap,
19 MmapMut};
20
21use std::ptr;
22
23use tof_dataclasses::io::RBEventMemoryStreamer;
24
25pub const UIO0 : &'static str = "/dev/uio0";
26pub const UIO1 : &'static str = "/dev/uio1";
27pub const UIO2 : &'static str = "/dev/uio2";
28
29pub const DATABUF_TOTAL_SIZE : usize = 66524928;
38pub const EVENT_SIZE : usize = 18530;
39pub const UIO1_MIN_OCCUPANCY : u32 = 68157440;
41pub const UIO2_MIN_OCCUPANCY : u32 = 135266304;
42
43pub const UIO1_MAX_OCCUPANCY : u32 = 117089408;
44pub const UIO2_MAX_OCCUPANCY : u32 = 201788800;
45
46pub const SIZEOF_U32 : usize = 4;
49
50
51#[derive(Debug, Copy, Clone)]
52pub enum RegisterError {
53 RegisterTimeOut,
54 MMapFail,
55 Unknown,
56}
57
58impl fmt::Display for RegisterError {
59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60 let etype : String;
61 match self {
62 RegisterError::RegisterTimeOut => {
63 etype = String::from("RegisterTimeOut");
64 },
65 RegisterError::Unknown => {
66 etype = String::from("Unknown");
67 },
68 _ => {
69 etype = String::from("not defined");
70 }
71 }
72 write!(f, "<RegisterError: {}>", etype)
73 }
74}
75
76impl Error for RegisterError {
77}
78
79
80#[derive(Debug, Copy, Clone)]
85pub enum RamBuffer {
86 A,
87 B,
88 }
90
91impl RamBuffer {
92 pub fn invert(&self) -> RamBuffer {
93 match self {
94 RamBuffer::A => {return RamBuffer::B},
95 RamBuffer::B => {return RamBuffer::A}
96 }
97 }
98}
99
100pub fn size_in_events(size : usize) -> usize {
106 size/EVENT_SIZE
107}
108
109pub fn map_physical_mem_read(addr_space : &str,
115 addr: u32,
116 len: usize) -> Result<Mmap, Box<dyn Error>> {
117 let m = unsafe {
118 memmap::MmapOptions::new()
119 .offset(addr as u64)
120 .len(len)
121 .map(&File::open(addr_space)?)?
122 };
123 Ok(m)
124}
125
126pub fn map_physical_mem_write(addr_space : &str,
138 addr : u32,
139 len : usize)
140 -> Result<MmapMut, Box<dyn Error>> {
141 let m = unsafe {
142 memmap::MmapOptions::new()
143 .offset(addr as u64)
144 .len(len)
145 .map_mut(&File::options()
146 .read(true)
147 .write(true)
148 .open(addr_space)?)?
149 };
150 Ok(m)
151}
152
153pub fn read_control_reg(addr : u32)
163 -> Result<u32, RegisterError>
164 where
165 u32: std::fmt::LowerHex, {
166
167 let m = match map_physical_mem_read(UIO0, addr, SIZEOF_U32) {
169 Ok(m) => m,
170 Err(err) => {
171 error!("Failed to mmap: {:?}", err);
172 return Err(RegisterError::MMapFail);
173 }
174 };
175 let p = m.as_ptr() as *const u32;
176 let value : u32;
177 unsafe {
178 value = std::ptr::read_volatile(p.offset(0));
179 }
180 Ok(value)
181}
182
183pub fn write_control_reg(addr : u32,
185 data : u32)
186 -> Result<(), RegisterError>
187 where
188 u32: std::fmt::LowerHex, {
189
190 trace!("Attempting to write {data} at addr {addr}");
191 let m = match map_physical_mem_write(UIO0,addr,SIZEOF_U32) {
193 Ok(m) => m,
194 Err(err) => {
195 warn!("[write_control_reg] Failed to mmap! {:?}", err);
196 return Err(RegisterError::MMapFail);
197 }
198 };
199 let p = m.as_ptr() as *mut u32;
200 unsafe {
201 std::ptr::write_volatile(p.offset(0), data);
202 }
203 Ok(())
204}
205
206
207pub fn read_data_buffer(which : &RamBuffer,
216 size : usize)
217 -> Result<Vec::<u8>, RegisterError>
218 where
219 u32: std::fmt::LowerHex, {
220
221 let addr_space;
222 match which {
223 RamBuffer::A => addr_space = UIO1,
224 RamBuffer::B => addr_space = UIO2
225 }
226 let mut bytestream = Vec::<u8>::with_capacity(size);
231 let m = match map_physical_mem_read(addr_space, 0x0, size) {
232 Ok(m) => m,
234 Err(err) => {
235 warn!("Failed to mmap! {:?}", err);
237 return Err(RegisterError::MMapFail);
238 }
239 };
240
241 let p = m.as_ptr() as *const u8;
244 let slice = ptr::slice_from_raw_parts(p, size);
246 unsafe {
247 bytestream.extend_from_slice(&*slice);
249 }
250 Ok(bytestream)
251}
252
253pub fn read_buffer_into_streamer(which : &RamBuffer,
262 size : usize,
263 streamer : &mut RBEventMemoryStreamer)
264 -> Result<(), RegisterError>
265 where
266 u32: std::fmt::LowerHex, {
267
268 let addr_space;
269 match which {
270 RamBuffer::A => addr_space = UIO1,
271 RamBuffer::B => addr_space = UIO2
272 }
273 let m = match map_physical_mem_read(addr_space, 0x0, size) {
274 Ok(m) => m,
276 Err(err) => {
277 warn!("Failed to mmap: {:?}", err);
278 return Err(RegisterError::MMapFail);
279 }
280 };
281 let p = m.as_ptr() as *const u8;
282 let slice = ptr::slice_from_raw_parts(p, size);
284 let mut bytestream = Vec::<u8>::with_capacity(200000);
286 println!("Trying to get bytestream from raw parts!");
287 unsafe {
288 bytestream.extend_from_slice(&*slice);
290 }
291 streamer.consume(&mut bytestream);
292 println!(".. done!");
293 Ok(())
295}
296
297