use bindings;
#[derive(Debug, PartialEq)]
pub enum BitOrder {
MsbFirst,
LsbFirst,
}
#[derive(Debug, PartialEq)]
pub enum Mode {
Mode0,
Mode1,
Mode2,
Mode3
}
#[derive(Debug, PartialEq)]
pub struct SpiSettings {
max_clock: u32,
order: BitOrder,
mode: Mode,
ctar: RenderedSpi,
}
type RenderedSpi = u32;
impl SpiSettings {
pub fn new(max_clock: u32, order: BitOrder, mode: Mode) -> SpiSettings {
let mut new = SpiSettings {
max_clock: max_clock,
order: order,
mode: mode,
ctar: 0
};
new.ctar = new.render();
new
}
fn render(&self) -> RenderedSpi {
let mut t = unsafe {
let mut t_out: u32 = bindings::SPISettings_ctar_div_table[0] as u32;
for t in bindings::SPISettings_ctar_div_table.iter() {
t_out = *t as u32;
if self.max_clock > (bindings::F_BUS as u32 / t_out) {
break;
}
}
t_out
};
let mut c: u32 = (7 & 15) << 27;
if self.order == BitOrder::LsbFirst {
c |= 0x01000000;
}
match self.mode {
Mode::Mode0 => {},
Mode::Mode1 => {
c |= 0x02000000;
t = (t & 0xFFFF0FFF) | ((t & 0xF000) >> 4);
},
Mode::Mode2 => {
c |= 0x04000000
},
Mode::Mode3 => {
c |= 0x06000000;
t = (t & 0xFFFF0FFF) | ((t & 0xF000) >> 4);
},
}
c | t
}
}
#[derive(Copy, Clone)]
pub struct Spi;
use bindings::SPIClass;
impl Spi {
pub fn begin(&self) {
unsafe {
SPIClass::begin();
}
}
pub fn begin_transaction(&self, settings: &SpiSettings) {
unsafe {
SPIClass::beginTransaction(bindings::SPISettings{
ctar: settings.ctar,
});
}
}
pub fn end_transaction(&self) {
unsafe {
SPIClass::endTransaction();
}
}
pub fn transfer_replace(&self, data: &mut [u8]) {
for mut byte in data.iter_mut() {
*byte = unsafe {
SPIClass::transfer(*byte)
}
}
}
}