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