1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use embedded_hal::blocking::spi::{Transfer, Write};
use embedded_hal::digital::v2::{OutputPin, InputPin};
use embedded_hal::blocking::delay::DelayMs;
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, Delay> Cursed for Wrapper<Spi, SpiError, Output, Input, PinError, Delay> {}
impl <Spi, SpiError, Output, Input, PinError, Delay> Wrapper<Spi, SpiError, Output, Input, PinError, Delay>
where
Spi: Transfer<u8, Error = SpiError> + Write<u8, Error = SpiError>,
Output: OutputPin<Error = PinError>,
Input: InputPin<Error = PinError>,
Delay: DelayMs<u32>,
{
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);
}
}