tof_control/
memory.rs

1use log::{trace, warn};
2use std::error::Error;
3use std::fs::File;
4
5use memmap::{Mmap, MmapMut};
6
7use crate::constant::*;
8
9pub const SIZEOF_U32: usize = 4;
10
11#[derive(Debug, Copy, Clone)]
12pub struct RegisterError {}
13
14pub fn map_physical_mem_read(
15    addr_space: &str,
16    addr: u32,
17    len: usize,
18) -> Result<Mmap, Box<dyn Error>> {
19    let m = unsafe {
20        memmap::MmapOptions::new()
21            .offset(addr as u64)
22            .len(len)
23            .map(&File::open(addr_space)?)?
24    };
25    Ok(m)
26}
27
28pub fn map_physical_mem_write(
29    addr_space: &str,
30    addr: u32,
31    len: usize,
32) -> Result<MmapMut, Box<dyn Error>> {
33    let m = unsafe {
34        memmap::MmapOptions::new()
35            .offset(addr as u64)
36            .len(len)
37            .map_mut(&File::options().read(true).write(true).open(addr_space)?)?
38    };
39    Ok(m)
40}
41
42pub fn read_control_reg(addr: u32) -> Result<u32, RegisterError>
43where
44    u32: std::fmt::LowerHex,
45{
46    let m = match map_physical_mem_read(RB_UIO0, addr, SIZEOF_U32) {
47        Ok(m) => m,
48        Err(err) => {
49            let error = RegisterError {};
50            warn!("Failed to mmap: Err={:?}", err);
51            return Err(error);
52        }
53    };
54    let p = m.as_ptr() as *const u32;
55    let value: u32;
56    unsafe {
57        value = std::ptr::read_volatile(p.offset(0));
58    }
59    Ok(value)
60}
61
62pub fn write_control_reg(addr: u32, data: u32) -> Result<(), RegisterError>
63where
64    u32: std::fmt::LowerHex,
65{
66    trace!("Attempting to write {data} at addr {addr}");
67
68    let m = match map_physical_mem_write(RB_UIO0, addr, SIZEOF_U32) {
69        Ok(m) => m,
70        Err(err) => {
71            let error = RegisterError {};
72            warn!("[write_control_reg] Failed to mmap: Err={:?}", err);
73            return Err(error);
74        }
75    };
76    let p = m.as_ptr() as *mut u32;
77    unsafe {
78        std::ptr::write_volatile(p.offset(0), data);
79    }
80    Ok(())
81}