• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eldruin / bmi160-rs / 8960953028

05 May 2024 08:31PM UTC coverage: 92.553% (+6.1%) from 86.432%
8960953028

push

github

eldruin
Use llvm-cov for code coverage

348 of 376 relevant lines covered (92.55%)

5.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

63.79
/src/interface.rs
1
//! I2C/SPI interfaces
2

3
use crate::{private, Error};
4
use embedded_hal::{i2c, spi::SpiDevice};
5

6
const I2C_DEV_BASE_ADDR: u8 = 0x68;
7

8
/// I2C interface
9
#[derive(Debug)]
10
pub struct I2cInterface<I2C> {
11
    pub(crate) i2c: I2C,
12
    pub(crate) address: u8,
13
}
14

15
/// SPI interface
16
#[derive(Debug)]
17
pub struct SpiInterface<SPI> {
18
    pub(crate) spi: SPI,
19
}
20

21
/// Possible slave addresses
22
#[derive(Debug, Clone, Copy, PartialEq)]
23
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24
pub enum SlaveAddr {
25
    /// Default slave address
26
    Default,
27
    /// Alternative slave address providing bit value for the SDO pin
28
    Alternative(bool),
29
}
30

31
impl Default for SlaveAddr {
32
    /// Default slave address
33
    fn default() -> Self {
38✔
34
        SlaveAddr::Default
38✔
35
    }
38✔
36
}
37

38
impl SlaveAddr {
39
    /// The numerical address of the device
40
    pub fn addr(self) -> u8 {
40✔
41
        match self {
40✔
42
            SlaveAddr::Default => I2C_DEV_BASE_ADDR,
38✔
43
            SlaveAddr::Alternative(false) => I2C_DEV_BASE_ADDR,
1✔
44
            SlaveAddr::Alternative(true) => I2C_DEV_BASE_ADDR | 1,
1✔
45
        }
46
    }
40✔
47
}
48

49
/// Write data
50
pub trait WriteData: private::Sealed {
51
    /// Error type
52
    type Error;
53
    /// Write to an u8 register
54
    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error>;
55
    /// Write data. The first element corresponds to the starting address.
56
    fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error>;
57
}
58

59
impl<I2C, E> WriteData for I2cInterface<I2C>
60
where
61
    I2C: i2c::I2c<Error = E>,
62
{
63
    type Error = Error<E>;
64
    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
17✔
65
        let payload: [u8; 2] = [register, data];
17✔
66
        let addr = self.address;
17✔
67
        self.i2c.write(addr, &payload).map_err(Error::Comm)
17✔
68
    }
17✔
69

70
    fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
×
71
        let addr = self.address;
×
72
        self.i2c.write(addr, payload).map_err(Error::Comm)
×
73
    }
×
74
}
75

76
impl<SPI, CommE> WriteData for SpiInterface<SPI>
77
where
78
    SPI: SpiDevice<u8, Error = CommE>,
79
{
80
    type Error = Error<CommE>;
81
    fn write_register(&mut self, register: u8, data: u8) -> Result<(), Self::Error> {
×
82
        let payload: [u8; 2] = [register, data];
×
83
        self.spi.write(&payload).map_err(Error::Comm)
×
84
    }
×
85

86
    fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
×
87
        self.spi.write(payload).map_err(Error::Comm)
×
88
    }
×
89
}
90

91
/// Read data
92
pub trait ReadData: private::Sealed {
93
    /// Error type
94
    type Error;
95
    /// Read an u8 register
96
    fn read_register(&mut self, register: u8) -> Result<u8, Self::Error>;
97
    /// Read some data. The first element corresponds to the starting address.
98
    fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error>;
99
}
100

101
impl<I2C, E> ReadData for I2cInterface<I2C>
102
where
103
    I2C: i2c::I2c<Error = E>,
104
{
105
    type Error = Error<E>;
106
    fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
14✔
107
        let mut data = [0];
14✔
108
        let addr = self.address;
14✔
109
        self.i2c
14✔
110
            .write_read(addr, &[register], &mut data)
14✔
111
            .map_err(Error::Comm)
14✔
112
            .and(Ok(data[0]))
14✔
113
    }
14✔
114

115
    fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
4✔
116
        let len = payload.len();
4✔
117
        let addr = self.address;
4✔
118
        self.i2c
4✔
119
            .write_read(addr, &[payload[0]], &mut payload[1..len])
4✔
120
            .map_err(Error::Comm)
4✔
121
    }
4✔
122
}
123

124
impl<SPI, CommE> ReadData for SpiInterface<SPI>
125
where
126
    SPI: SpiDevice<u8, Error = CommE>,
127
{
128
    type Error = Error<CommE>;
129
    fn read_register(&mut self, register: u8) -> Result<u8, Self::Error> {
×
130
        let mut data = [register + 0x80, 0];
×
131
        self.spi.transfer_in_place(&mut data).map_err(Error::Comm)?;
×
132
        Ok(data[1])
×
133
    }
×
134

135
    fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Self::Error> {
×
136
        payload[0] += 0x80;
×
137
        self.spi.transfer_in_place(payload).map_err(Error::Comm)?;
×
138
        Ok(())
×
139
    }
×
140
}
141

142
#[cfg(test)]
143
mod tests {
144
    use super::SlaveAddr;
145
    use super::I2C_DEV_BASE_ADDR as ADDR;
146

147
    #[test]
148
    fn can_get_default_address() {
1✔
149
        let addr = SlaveAddr::default();
1✔
150
        assert_eq!(ADDR, addr.addr());
1✔
151
    }
1✔
152

153
    #[test]
154
    fn can_generate_alternative_addresses() {
1✔
155
        assert_eq!(ADDR, SlaveAddr::Alternative(false).addr());
1✔
156
        assert_eq!(ADDR | 1, SlaveAddr::Alternative(true).addr());
1✔
157
    }
1✔
158
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc