-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdriver.rs
94 lines (83 loc) · 2.49 KB
/
driver.rs
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
use crate::modules::Reg;
use embedded_hal::{
delay::DelayNs,
i2c::{I2c, Operation, SevenBitAddress},
};
const DELAY_TIME: u32 = 125;
/// Blanket trait for anything that implements I2C and a delay
pub trait Driver: I2c + DelayNs {}
impl<T> Driver for T where T: I2c + DelayNs {}
macro_rules! impl_integer_write {
($fn:ident $nty:tt) => {
fn $fn(
&mut self,
addr: SevenBitAddress,
reg: &Reg,
value: $nty,
) -> Result<(), Self::Error> {
self.register_write(addr, reg, &<$nty>::to_be_bytes(value))
}
};
}
macro_rules! impl_integer_read {
($fn:ident $nty:tt) => {
fn $fn(&mut self, addr: SevenBitAddress, reg: &Reg) -> Result<$nty, Self::Error> {
self.register_read::<{ ($nty::BITS / 8) as usize }>(addr, reg)
.map($nty::from_be_bytes)
}
};
}
pub trait DriverExt {
type Error;
fn register_read<const N: usize>(
&mut self,
addr: SevenBitAddress,
reg: &Reg,
) -> Result<[u8; N], Self::Error>;
fn register_write(
&mut self,
addr: SevenBitAddress,
reg: &Reg,
bytes: &[u8],
) -> Result<(), Self::Error>;
impl_integer_read! { read_u8 u8 }
impl_integer_read! { read_u16 u16 }
impl_integer_read! { read_u32 u32 }
impl_integer_read! { read_u64 u64 }
impl_integer_read! { read_i8 i8 }
impl_integer_read! { read_i16 i16 }
impl_integer_read! { read_i32 i32 }
impl_integer_read! { read_i64 i64 }
impl_integer_write! { write_u8 u8 }
impl_integer_write! { write_u16 u16 }
impl_integer_write! { write_u32 u32 }
impl_integer_write! { write_u64 u64 }
impl_integer_write! { write_i8 i8 }
impl_integer_write! { write_i16 i16 }
impl_integer_write! { write_i32 i32 }
impl_integer_write! { write_i64 i64 }
}
impl<T: Driver> DriverExt for T {
type Error = T::Error;
fn register_read<const N: usize>(
&mut self,
addr: SevenBitAddress,
reg: &Reg,
) -> Result<[u8; N], Self::Error> {
let mut buffer = [0u8; N];
self.write(addr, reg)?;
self.delay_us(DELAY_TIME);
self.read(addr, &mut buffer)?;
Ok(buffer)
}
fn register_write(
&mut self,
addr: SevenBitAddress,
reg: &Reg,
bytes: &[u8],
) -> Result<(), Self::Error> {
self.transaction(addr, &mut [Operation::Write(reg), Operation::Write(bytes)])?;
self.delay_us(DELAY_TIME);
Ok(())
}
}