pub mod memory_map;
use crate::{error::Error, Device, Sensors};
use memory_map::*;
use nix::fcntl::{open, OFlag}; use nix::sys::stat::Mode;
use nix::unistd::close;
use nix::{ioctl_read_bad, ioctl_write_ptr_bad};
use std::sync::Mutex;
ioctl_read_bad!(read, ioctl_code::READ, [i32]);
ioctl_write_ptr_bad!(write, ioctl_code::WRITE, [u8]);
pub struct Bus {
pub device_file: &'static str,
pub regmap_fd: std::os::unix::io::RawFd,
pub device_name: Device,
pub device_leds: u8,
pub usage: Mutex<()>,
}
impl Bus {
pub fn init() -> Result<Bus, Error> {
let mut bus = Bus {
device_file: "/dev/matrixio_regmap",
regmap_fd: 0,
device_name: Device::Unknown,
device_leds: 0,
usage: Mutex::new(()),
};
bus.regmap_fd = open(bus.device_file, OFlag::O_RDWR, Mode::empty())?;
bus.device_name = bus.get_device_name()?;
bus.device_leds = match bus.device_name {
Device::Creator => 35,
Device::Voice => 18,
_ => panic!("Cannot determine number of LEDs on device (This is a hard-coded value)."),
};
Ok(bus)
}
pub fn write(&self, address: u16, write_buffer: &mut [u8], bytes: i32) {
self.usage.lock().unwrap();
unsafe {
let new_buffer = std::mem::transmute::<&mut [u8], &mut [i32]>(write_buffer);
let mut x = Vec::<i32>::new();
x.push(address as i32);
x.push(bytes);
x.extend(new_buffer.to_vec());
let y = std::mem::transmute::<&mut [i32], &mut [u8]>(&mut x);
write(self.regmap_fd, &y[..]).expect("error in IOCTL WRITE");
}
}
pub fn read(&self, address: u16, read_buffer: &mut [i32], bytes: i32) {
self.usage.lock().unwrap();
read_buffer[0] = address as i32;
read_buffer[1] = bytes;
unsafe {
read(self.regmap_fd, read_buffer).unwrap();
}
}
pub fn close(&self) {
close(self.regmap_fd).unwrap();
}
fn get_device_name(&self) -> Result<Device, Error> {
let mut data: [i32; 4] = [0; 4];
self.read(fpga_address::CONF as u16, &mut data, 8);
let device_name = data[2];
match device_name {
device_info::MATRIX_CREATOR => Ok(Device::Creator),
device_info::MATRIX_VOICE => Ok(Device::Voice),
_ => Err(Error::UnknownDevice),
}
}
}