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

eldruin / lsm303agr-rs / 9599194769

20 Jun 2024 02:21PM UTC coverage: 86.275% (+0.08%) from 86.196%
9599194769

Pull #31

github

web-flow
Merge c444d3f43 into 322cb031a
Pull Request #31: implement embedded-hal-async traits using maybe-async-cfg

102 of 111 new or added lines in 5 files covered. (91.89%)

4 existing lines in 2 files now uncovered.

528 of 612 relevant lines covered (86.27%)

2.7 hits per line

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

83.33
/src/device_impl.rs
1
use maybe_async_cfg::maybe;
2

3
use crate::{
4
    interface::{I2cInterface, ReadData, SpiInterface, WriteData},
5
    mode,
6
    register_address::{
7
        CfgRegAM, CfgRegBM, CfgRegCM, CtrlReg1A, CtrlReg3A, CtrlReg4A, CtrlReg5A, FifoCtrlRegA,
8
        StatusRegA, StatusRegAuxA, StatusRegM, TempCfgRegA, WhoAmIA, WhoAmIM,
9
    },
10
    Acceleration, AccelerometerId, Error, FifoMode, Interrupt, Lsm303agr, MagnetometerId,
11
    PhantomData, Status, Temperature, TemperatureStatus,
12
};
13

14
impl<I2C> Lsm303agr<I2cInterface<I2C>, mode::MagOneShot> {
15
    /// Create new instance of the LSM303AGR device communicating through I2C.
16
    pub fn new_with_i2c(i2c: I2C) -> Self {
7✔
17
        Lsm303agr {
18
            iface: I2cInterface { i2c },
7✔
19
            ctrl_reg1_a: CtrlReg1A::default(),
7✔
20
            ctrl_reg3_a: CtrlReg3A::default(),
7✔
21
            ctrl_reg4_a: CtrlReg4A::default(),
7✔
22
            ctrl_reg5_a: CtrlReg5A::default(),
7✔
23
            cfg_reg_a_m: CfgRegAM::default(),
7✔
24
            cfg_reg_b_m: CfgRegBM::default(),
7✔
25
            cfg_reg_c_m: CfgRegCM::default(),
7✔
26
            temp_cfg_reg_a: TempCfgRegA::default(),
7✔
27
            fifo_ctrl_reg_a: FifoCtrlRegA::default(),
7✔
28
            accel_odr: None,
29
            _mag_mode: PhantomData,
30
        }
31
    }
32
}
33

34
impl<I2C, MODE> Lsm303agr<I2cInterface<I2C>, MODE> {
35
    /// Destroy driver instance, return I2C bus.
36
    pub fn destroy(self) -> I2C {
×
37
        self.iface.i2c
9✔
38
    }
39
}
40

41
impl<SPIXL, SPIMAG> Lsm303agr<SpiInterface<SPIXL, SPIMAG>, mode::MagOneShot> {
42
    /// Create new instance of the LSM303AGR device communicating through SPI.
43
    pub fn new_with_spi(spi_accel: SPIXL, spi_mag: SPIMAG) -> Self {
4✔
44
        Lsm303agr {
45
            iface: SpiInterface {
4✔
46
                spi_xl: spi_accel,
47
                spi_mag,
48
            },
49
            ctrl_reg1_a: CtrlReg1A::default(),
4✔
50
            ctrl_reg3_a: CtrlReg3A::default(),
4✔
51
            ctrl_reg4_a: CtrlReg4A::default(),
4✔
52
            ctrl_reg5_a: CtrlReg5A::default(),
4✔
53
            cfg_reg_a_m: CfgRegAM::default(),
4✔
54
            cfg_reg_b_m: CfgRegBM::default(),
4✔
55
            cfg_reg_c_m: CfgRegCM::default(),
4✔
56
            temp_cfg_reg_a: TempCfgRegA::default(),
4✔
57
            fifo_ctrl_reg_a: FifoCtrlRegA::default(),
4✔
58
            accel_odr: None,
59
            _mag_mode: PhantomData,
60
        }
61
    }
62
}
63

64
impl<SPIXL, SPIMAG, MODE> Lsm303agr<SpiInterface<SPIXL, SPIMAG>, MODE> {
65
    /// Destroy driver instance, return SPI bus instance and chip select pin.
66
    pub fn destroy(self) -> (SPIXL, SPIMAG) {
4✔
67
        (self.iface.spi_xl, self.iface.spi_mag)
4✔
68
    }
69
}
70

71
#[maybe(
72
    sync(
73
        cfg(not(feature = "async")),
74
        keep_self,
75
    ),
76
    async (
77
        cfg(feature = "async"),
78
        keep_self,
79
    )
80
)]
81
impl<DI, CommE, MODE> Lsm303agr<DI, MODE>
82
where
83
    DI: ReadData<Error = Error<CommE>> + WriteData<Error = Error<CommE>>,
84
{
85
    /// Initialize registers
86
    pub async fn init(&mut self) -> Result<(), Error<CommE>> {
2✔
87
        self.acc_enable_temp().await?; // Also enables BDU.
2✔
88
        self.mag_enable_bdu().await
2✔
89
    }
90

91
    /// Enable block data update for accelerometer.
92
    #[inline]
93
    async fn acc_enable_bdu(&mut self) -> Result<(), Error<CommE>> {
2✔
94
        let reg4 = self.ctrl_reg4_a | CtrlReg4A::BDU;
2✔
95
        self.iface.write_accel_register(reg4).await?;
4✔
96
        self.ctrl_reg4_a = reg4;
2✔
97

98
        Ok(())
2✔
99
    }
100

101
    /// Enable the temperature sensor.
102
    #[inline]
103
    async fn acc_enable_temp(&mut self) -> Result<(), Error<CommE>> {
2✔
104
        self.acc_enable_bdu().await?;
2✔
105

106
        let temp_cfg_reg = self.temp_cfg_reg_a | TempCfgRegA::TEMP_EN;
2✔
107
        self.iface.write_accel_register(temp_cfg_reg).await?;
4✔
108
        self.temp_cfg_reg_a = temp_cfg_reg;
2✔
109

110
        Ok(())
2✔
111
    }
112

113
    /// Enable block data update for magnetometer.
114
    #[inline]
115
    async fn mag_enable_bdu(&mut self) -> Result<(), Error<CommE>> {
2✔
116
        let regc = self.cfg_reg_c_m | CfgRegCM::BDU;
2✔
117
        self.iface.write_mag_register(regc).await?;
4✔
118
        self.cfg_reg_c_m = regc;
2✔
119

120
        Ok(())
2✔
121
    }
122

123
    /// Set the accelerometer FIFO mode and full threshold.
124
    ///
125
    /// The threshold is clamped to \[0, 31\].
126
    pub async fn acc_set_fifo_mode(&mut self, mode: FifoMode, fth: u8) -> Result<(), Error<CommE>> {
1✔
127
        let mut reg5 = self.ctrl_reg5_a;
1✔
128
        reg5.set(CtrlReg5A::FIFO_EN, mode != FifoMode::Bypass);
1✔
129
        self.iface.write_accel_register(reg5).await?;
1✔
130
        self.ctrl_reg5_a = reg5;
1✔
131

132
        let fifo_ctrl = self
1✔
133
            .fifo_ctrl_reg_a
×
134
            .with_mode(mode)
×
135
            .with_full_threshold(fth);
×
136
        self.iface.write_accel_register(fifo_ctrl).await?;
2✔
137
        self.fifo_ctrl_reg_a = fifo_ctrl;
1✔
138

139
        Ok(())
1✔
140
    }
141

142
    /// Enable accelerometer interrupt.
143
    pub async fn acc_enable_interrupt(&mut self, interrupt: Interrupt) -> Result<(), Error<CommE>> {
1✔
144
        let reg3 = self.ctrl_reg3_a.with_interrupt(interrupt);
1✔
145
        self.iface.write_accel_register(reg3).await?;
2✔
146
        self.ctrl_reg3_a = reg3;
1✔
147

148
        Ok(())
1✔
149
    }
150

151
    /// Disable accelerometer interrupt.
152
    pub async fn acc_disable_interrupt(&mut self, interrupt: Interrupt) -> Result<(), Error<CommE>> {
1✔
153
        let reg3 = self.ctrl_reg3_a.without_interrupt(interrupt);
1✔
154
        self.iface.write_accel_register(reg3).await?;
2✔
155
        self.ctrl_reg3_a = reg3;
1✔
156

157
        Ok(())
1✔
158
    }
159

160
    /// Configure the DRDY pin as a digital output.
NEW
161
    pub async fn mag_enable_int(&mut self) -> Result<(), Error<CommE>> {
×
162
        let regc = self.cfg_reg_c_m | CfgRegCM::INT_MAG;
×
NEW
163
        self.iface.write_mag_register(regc).await?;
×
164
        self.cfg_reg_c_m = regc;
×
165

166
        Ok(())
×
167
    }
168

169
    /// Enable magnetometer low-pass filter.
170
    pub async fn mag_enable_low_pass_filter(&mut self) -> Result<(), Error<CommE>> {
1✔
171
        let regb = self.cfg_reg_b_m.union(CfgRegBM::LPF);
1✔
172
        self.iface.write_mag_register(regb).await?;
2✔
173
        self.cfg_reg_b_m = regb;
1✔
174

175
        Ok(())
1✔
176
    }
177

178
    /// Disable magnetometer low-pass filter.
179
    pub async fn mag_disable_low_pass_filter(&mut self) -> Result<(), Error<CommE>> {
1✔
180
        let regb = self.cfg_reg_b_m.difference(CfgRegBM::LPF);
1✔
181
        self.iface.write_mag_register(regb).await?;
2✔
182
        self.cfg_reg_b_m = regb;
1✔
183

184
        Ok(())
1✔
185
    }
186

187
    /// Accelerometer status
188
    pub async fn accel_status(&mut self) -> Result<Status, Error<CommE>> {
1✔
189
        self.iface
1✔
190
            .read_accel_register::<StatusRegA>()
NEW
191
            .await
×
UNCOV
192
            .map(Status::new)
×
193
    }
194

195
    /// Get measured acceleration.
196
    pub async fn acceleration(&mut self) -> Result<Acceleration, Error<CommE>> {
2✔
197
        let (x, y, z) = self.iface.read_accel_3_double_registers::<Acceleration>().await?;
2✔
198

199
        Ok(Acceleration {
2✔
200
            x,
×
201
            y,
×
202
            z,
×
203
            mode: self.get_accel_mode().await,
2✔
204
            scale: self.get_accel_scale().await,
2✔
205
        })
206
    }
207

208
    /// Magnetometer status
209
    pub async fn mag_status(&mut self) -> Result<Status, Error<CommE>> {
2✔
210
        self.iface
2✔
211
            .read_mag_register::<StatusRegM>()
NEW
212
            .await
×
UNCOV
213
            .map(Status::new)
×
214
    }
215

216
    /// Get the accelerometer device ID.
217
    pub async fn accelerometer_id(&mut self) -> Result<AccelerometerId, Error<CommE>> {
2✔
218
        self.iface.read_accel_register::<WhoAmIA>().await
2✔
219
    }
220

221
    /// Get the magnetometer device ID.
222
    pub async fn magnetometer_id(&mut self) -> Result<MagnetometerId, Error<CommE>> {
2✔
223
        self.iface.read_mag_register::<WhoAmIM>().await
2✔
224
    }
225

226
    /// Get measured temperature.
227
    pub async fn temperature(&mut self) -> Result<Temperature, Error<CommE>> {
2✔
228
        self.iface.read_accel_double_register::<Temperature>().await
2✔
229
    }
230

231
    /// Temperature sensor status
232
    pub async fn temperature_status(&mut self) -> Result<TemperatureStatus, Error<CommE>> {
1✔
233
        self.iface
1✔
234
            .read_accel_register::<StatusRegAuxA>()
NEW
235
            .await
×
UNCOV
236
            .map(TemperatureStatus::new)
×
237
    }
238
}
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