@@ -79,6 +79,18 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
7979 self . i2c . write ( self . addr , data) . await
8080 }
8181
82+ /// Read multiple bytes from LIS2DW12 registers
83+ pub async fn read_regs ( & mut self , reg : Register , read_buf : & mut [ u8 ] ) -> Result < ( ) , I2C :: Error > {
84+ self . i2c . write_read ( self . addr , & [ reg as u8 ] , read_buf) . await ?;
85+ Ok ( ( ) )
86+ }
87+
88+ /// Write multiple bytes to LIS2DW12 registers
89+ /// NOTE: The first byte of the write data must be the starting register address to write
90+ pub async fn write_regs ( & mut self , data : & [ u8 ] ) -> Result < ( ) , I2C :: Error > {
91+ self . i2c . write ( self . addr , data) . await
92+ }
93+
8294 /// Modifies the specified register by first reading then setting or resetting specified bits
8395 /// If a bit is marked in both set and reset masks, then that bit will not be updated
8496 pub async fn modify_reg_bits (
@@ -117,10 +129,9 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
117129 /// Offset: 0 LSB = 25 deg C
118130 /// Scale: 16 LSB / deg C (Note: LSB bits 3..0 are unused 0, so the LSB is at bit 4)
119131 pub async fn temp_12bit ( & mut self ) -> Result < i16 , I2C :: Error > {
120- let mut temp: i16 = 0 ;
121- temp += ( ( self . read_reg ( Register :: TempOutHigh ) . await ?) as i16 ) << 8 ;
122- temp += ( self . read_reg ( Register :: TempOutLow ) . await ?) as i16 ;
123- Ok ( temp)
132+ let mut temp_bytes: [ u8 ; 2 ] = [ 0 ; 2 ] ;
133+ self . read_regs ( Register :: TempOutLow , & mut temp_bytes) . await ?;
134+ Ok ( i16:: from_le_bytes ( temp_bytes) )
124135 }
125136
126137 /// Reads the device temperature with 8 bit precision
@@ -137,31 +148,34 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
137148
138149 /// Reads the device acceleration register in the X axis
139150 pub async fn acc_x ( & mut self ) -> Result < i16 , I2C :: Error > {
140- let mut accx: i16 = 0 ;
141- accx += ( ( self . read_reg ( Register :: XOutHigh ) . await ?) as i16 ) << 8 ;
142- accx += ( self . read_reg ( Register :: XOutLow ) . await ?) as i16 ;
143- Ok ( accx)
151+ let mut accx_bytes: [ u8 ; 2 ] = [ 0 ; 2 ] ;
152+ self . read_regs ( Register :: XOutLow , & mut accx_bytes) . await ?;
153+ Ok ( i16:: from_le_bytes ( accx_bytes) )
144154 }
145155
146156 /// Reads the device acceleration register in the Y axis
147157 pub async fn acc_y ( & mut self ) -> Result < i16 , I2C :: Error > {
148- let mut accy: i16 = 0 ;
149- accy += ( ( self . read_reg ( Register :: YOutHigh ) . await ?) as i16 ) << 8 ;
150- accy += ( self . read_reg ( Register :: YOutLow ) . await ?) as i16 ;
151- Ok ( accy)
158+ let mut accy_bytes: [ u8 ; 2 ] = [ 0 ; 2 ] ;
159+ self . read_regs ( Register :: YOutLow , & mut accy_bytes) . await ?;
160+ Ok ( i16:: from_le_bytes ( accy_bytes) )
152161 }
153162
154163 /// Reads the device acceleration register in the Z axis
155164 pub async fn acc_z ( & mut self ) -> Result < i16 , I2C :: Error > {
156- let mut accz: i16 = 0 ;
157- accz += ( ( self . read_reg ( Register :: ZOutHigh ) . await ?) as i16 ) << 8 ;
158- accz += ( self . read_reg ( Register :: ZOutLow ) . await ?) as i16 ;
159- Ok ( accz)
165+ let mut accz_bytes: [ u8 ; 2 ] = [ 0 ; 2 ] ;
166+ self . read_regs ( Register :: ZOutLow , & mut accz_bytes) . await ?;
167+ Ok ( i16:: from_le_bytes ( accz_bytes) )
160168 }
161169
162170 /// Reads the 3D device acceleration from registers
163171 pub async fn acc ( & mut self ) -> Result < ( i16 , i16 , i16 ) , I2C :: Error > {
164- Ok ( ( self . acc_x ( ) . await ?, self . acc_y ( ) . await ?, self . acc_z ( ) . await ?) )
172+ let mut acc_bytes: [ u8 ; 6 ] = [ 0 ; 6 ] ;
173+ self . read_regs ( Register :: XOutLow , & mut acc_bytes) . await ?;
174+ Ok ( (
175+ i16:: from_le_bytes ( acc_bytes[ 0 ..2 ] . try_into ( ) . unwrap ( ) ) ,
176+ i16:: from_le_bytes ( acc_bytes[ 2 ..4 ] . try_into ( ) . unwrap ( ) ) ,
177+ i16:: from_le_bytes ( acc_bytes[ 4 ..6 ] . try_into ( ) . unwrap ( ) ) ,
178+ ) )
165179 }
166180
167181 /// Returns the 3D device acceleration in Gs
@@ -251,8 +265,15 @@ impl<I2C: embedded_hal_async::i2c::I2c> Lis2dw12<I2C> {
251265
252266 /// Returns free fall duration by stitching FF_DUR5 from WAKE_UP_DUR register onto FF register output
253267 pub async fn free_fall_duration ( & mut self ) -> Result < u8 , I2C :: Error > {
254- let ff_reg: FreeFallReg = self . read_reg ( Register :: FreeFall ) . await ?. into ( ) ;
255- let wu_reg: WakeUpDurationReg = self . read_reg ( Register :: WakeUpDuration ) . await ?. into ( ) ;
268+ let mut regs: [ u8 ; 2 ] = [ 0 ; 2 ] ;
269+ self . read_regs ( Register :: WakeUpDuration , & mut regs) . await ?;
270+
271+ // WakeUpDuration = 0x35
272+ let wu_reg: WakeUpDurationReg = regs[ 0 ] . into ( ) ;
273+
274+ // FreeFall = 0x36
275+ let ff_reg: FreeFallReg = regs[ 1 ] . into ( ) ;
276+
256277 let ff_dur: u8 = u8:: from ( ff_reg. ff_dur ( ) ) + ( u8:: from ( wu_reg. ff_dur5 ( ) ) << 5 ) ;
257278 Ok ( ff_dur)
258279 }
@@ -320,12 +341,13 @@ mod tests {
320341 #[ tokio:: test]
321342 async fn test_ff_dur ( ) {
322343 let ff_dur_expected: u8 = 0b010100 ;
323- let ff_reg: [ u8 ; 1 ] = [ 0b10100101 ] ;
324- let wud_reg: [ u8 ; 1 ] = [ 0b01011010 ] ;
325- let expectations = vec ! [
326- Transaction :: write_read( SA0_GND_ADDR , vec![ Register :: FreeFall as u8 ] , vec![ ff_reg[ 0 ] ] ) ,
327- Transaction :: write_read( SA0_GND_ADDR , vec![ Register :: WakeUpDuration as u8 ] , vec![ wud_reg[ 0 ] ] ) ,
328- ] ;
344+ let wud_reg: u8 = 0b01011010 ; // Wake Up Duration: 0x35
345+ let ff_reg: u8 = 0b10100101 ; // Free Fall: 0x36
346+ let expectations = vec ! [ Transaction :: write_read(
347+ SA0_GND_ADDR ,
348+ vec![ Register :: WakeUpDuration as u8 ] ,
349+ vec![ wud_reg, ff_reg] ,
350+ ) ] ;
329351 let i2c = Mock :: new ( & expectations) ;
330352 let mut accel = Lis2dw12 :: new_with_sa0_gnd ( i2c) ;
331353 let ff_dur: u8 = accel. free_fall_duration ( ) . await . unwrap ( ) ;
0 commit comments