use super::config::*;
use super::Gpio;
use crate::bus::memory_map::*;
use crate::error::Error;
use std::mem;
impl<'a> Gpio<'a> {
pub fn set_config<T>(&self, pin: u8, config: T) -> Result<(), Error>
where
T: PinConfig,
{
if pin > 15 {
panic!("The MATRIX Voice/Creator GPIO pins are from 0-15");
}
let (value, fpga_address_offset) = config.update_pin_map(pin, self)?;
self.bus_write(value, fpga_address_offset);
Ok(())
}
pub fn set_configs<T>(&self, pins: &[u8], config: T) -> Result<(), Error>
where
T: PinConfig,
{
for pin in pins.iter() {
let (value, fpga_address_offset) = config.update_pin_map(*pin, self)?;
self.bus_write(value, fpga_address_offset);
}
Ok(())
}
fn bus_write(&self, value: u16, address_offset: u16) {
let mut buffer: [u32; 3] = [0; 3];
buffer[0] = (fpga_address::GPIO + address_offset) as u32; buffer[1] = mem::size_of_val(&value) as u32; buffer[2] = value as u32;
self.bus
.write(unsafe { std::mem::transmute::<&mut [u32], &mut [u8]>(&mut buffer) });
}
pub fn set_prescaler(&self, bank: usize, prescaler: u16) -> Result<(), Error> {
let mask = 0xF << (4 * bank);
let mut prescaler = self.prescaler_bank_map.lock()?;
*prescaler = *prescaler << (4 * bank) | (*prescaler & !mask);
self.bus_write(*prescaler, fpga_address::GPIO + 3);
Ok(())
}
}