use embedded_hal::blocking::spi::{Transfer, Write};
use embedded_hal::digital::v2::{OutputPin, InputPin};
use crate::{Transactional};
use crate::wrapper::Wrapper;
pub trait Cursed {}
pub trait Conv {
fn to_c_ptr(&mut self) -> *mut libc::c_void;
fn from_c_ptr<'a>(ctx: *mut libc::c_void) -> &'a mut Self;
}
impl <T> Conv for T where
T: Cursed
{
fn to_c_ptr(&mut self) -> *mut libc::c_void {
self as *mut Self as *mut libc::c_void
}
fn from_c_ptr<'a>(ctx: *mut libc::c_void) -> &'a mut Self {
unsafe {
let s = ctx as *mut Self;
&mut *s
}
}
}
impl <Spi, SpiError, Output, Input, PinError> Cursed for Wrapper<Spi, SpiError, Output, Input, PinError> {}
impl <Spi, SpiError, Output, Input, PinError> Wrapper<Spi, SpiError, Output, Input, PinError>
where
Spi: Transfer<u8, Error = SpiError> + Write<u8, Error = SpiError>,
Output: OutputPin<Error = PinError>,
Input: InputPin<Error = PinError>,
{
pub extern fn ffi_spi_write(ctx: *mut libc::c_void, prefix: *mut u8, prefix_len: u16, data: *mut u8, data_len: u16) -> isize {
let s = Self::from_c_ptr(ctx);
let prefix: &[u8] = unsafe { core::slice::from_raw_parts(prefix, prefix_len as usize) };
let data: &[u8] = unsafe { core::slice::from_raw_parts(data, data_len as usize) };
match s.spi_write(&prefix, &data) {
Ok(_) => 0,
Err(e) => {
s.err = Some(e);
-1
},
}
}
pub extern fn ffi_spi_read(ctx: *mut libc::c_void, prefix: *mut u8, prefix_len: u16, data: *mut u8, data_len: u16) -> isize {
let s = Self::from_c_ptr(ctx);
let prefix: &[u8] = unsafe { core::slice::from_raw_parts(prefix, prefix_len as usize) };
let mut data: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(data, data_len as usize) };
match s.spi_read(&prefix, &mut data) {
Ok(_) => 0,
Err(e) => {
s.err = Some(e);
-1
},
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[derive(Debug, PartialEq)]
struct Something(bool);
impl Cursed for Something {}
#[test]
fn test_compat() {
let mut s = Something(true);
let p = s.to_c_ptr();
let r = Something::from_c_ptr(p);
assert_eq!(&s, r);
}
}