tinkerforge_async/bindings/
imu_v3_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! Full fledged AHRS with 9 degrees of freedom.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/IMUV3_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17    low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum ImuV3BrickletFunction {
24    GetAcceleration,
25    GetMagneticField,
26    GetAngularVelocity,
27    GetTemperature,
28    GetOrientation,
29    GetLinearAcceleration,
30    GetGravityVector,
31    GetQuaternion,
32    GetAllData,
33    SaveCalibration,
34    SetSensorConfiguration,
35    GetSensorConfiguration,
36    SetSensorFusionMode,
37    GetSensorFusionMode,
38    SetAccelerationCallbackConfiguration,
39    GetAccelerationCallbackConfiguration,
40    SetMagneticFieldCallbackConfiguration,
41    GetMagneticFieldCallbackConfiguration,
42    SetAngularVelocityCallbackConfiguration,
43    GetAngularVelocityCallbackConfiguration,
44    SetTemperatureCallbackConfiguration,
45    GetTemperatureCallbackConfiguration,
46    SetOrientationCallbackConfiguration,
47    GetOrientationCallbackConfiguration,
48    SetLinearAccelerationCallbackConfiguration,
49    GetLinearAccelerationCallbackConfiguration,
50    SetGravityVectorCallbackConfiguration,
51    GetGravityVectorCallbackConfiguration,
52    SetQuaternionCallbackConfiguration,
53    GetQuaternionCallbackConfiguration,
54    SetAllDataCallbackConfiguration,
55    GetAllDataCallbackConfiguration,
56    GetSpitfpErrorCount,
57    SetBootloaderMode,
58    GetBootloaderMode,
59    SetWriteFirmwarePointer,
60    WriteFirmware,
61    SetStatusLedConfig,
62    GetStatusLedConfig,
63    GetChipTemperature,
64    Reset,
65    WriteUid,
66    ReadUid,
67    GetIdentity,
68    CallbackAcceleration,
69    CallbackMagneticField,
70    CallbackAngularVelocity,
71    CallbackTemperature,
72    CallbackLinearAcceleration,
73    CallbackGravityVector,
74    CallbackOrientation,
75    CallbackQuaternion,
76    CallbackAllData,
77}
78impl From<ImuV3BrickletFunction> for u8 {
79    fn from(fun: ImuV3BrickletFunction) -> Self {
80        match fun {
81            ImuV3BrickletFunction::GetAcceleration => 1,
82            ImuV3BrickletFunction::GetMagneticField => 2,
83            ImuV3BrickletFunction::GetAngularVelocity => 3,
84            ImuV3BrickletFunction::GetTemperature => 4,
85            ImuV3BrickletFunction::GetOrientation => 5,
86            ImuV3BrickletFunction::GetLinearAcceleration => 6,
87            ImuV3BrickletFunction::GetGravityVector => 7,
88            ImuV3BrickletFunction::GetQuaternion => 8,
89            ImuV3BrickletFunction::GetAllData => 9,
90            ImuV3BrickletFunction::SaveCalibration => 10,
91            ImuV3BrickletFunction::SetSensorConfiguration => 11,
92            ImuV3BrickletFunction::GetSensorConfiguration => 12,
93            ImuV3BrickletFunction::SetSensorFusionMode => 13,
94            ImuV3BrickletFunction::GetSensorFusionMode => 14,
95            ImuV3BrickletFunction::SetAccelerationCallbackConfiguration => 15,
96            ImuV3BrickletFunction::GetAccelerationCallbackConfiguration => 16,
97            ImuV3BrickletFunction::SetMagneticFieldCallbackConfiguration => 17,
98            ImuV3BrickletFunction::GetMagneticFieldCallbackConfiguration => 18,
99            ImuV3BrickletFunction::SetAngularVelocityCallbackConfiguration => 19,
100            ImuV3BrickletFunction::GetAngularVelocityCallbackConfiguration => 20,
101            ImuV3BrickletFunction::SetTemperatureCallbackConfiguration => 21,
102            ImuV3BrickletFunction::GetTemperatureCallbackConfiguration => 22,
103            ImuV3BrickletFunction::SetOrientationCallbackConfiguration => 23,
104            ImuV3BrickletFunction::GetOrientationCallbackConfiguration => 24,
105            ImuV3BrickletFunction::SetLinearAccelerationCallbackConfiguration => 25,
106            ImuV3BrickletFunction::GetLinearAccelerationCallbackConfiguration => 26,
107            ImuV3BrickletFunction::SetGravityVectorCallbackConfiguration => 27,
108            ImuV3BrickletFunction::GetGravityVectorCallbackConfiguration => 28,
109            ImuV3BrickletFunction::SetQuaternionCallbackConfiguration => 29,
110            ImuV3BrickletFunction::GetQuaternionCallbackConfiguration => 30,
111            ImuV3BrickletFunction::SetAllDataCallbackConfiguration => 31,
112            ImuV3BrickletFunction::GetAllDataCallbackConfiguration => 32,
113            ImuV3BrickletFunction::GetSpitfpErrorCount => 234,
114            ImuV3BrickletFunction::SetBootloaderMode => 235,
115            ImuV3BrickletFunction::GetBootloaderMode => 236,
116            ImuV3BrickletFunction::SetWriteFirmwarePointer => 237,
117            ImuV3BrickletFunction::WriteFirmware => 238,
118            ImuV3BrickletFunction::SetStatusLedConfig => 239,
119            ImuV3BrickletFunction::GetStatusLedConfig => 240,
120            ImuV3BrickletFunction::GetChipTemperature => 242,
121            ImuV3BrickletFunction::Reset => 243,
122            ImuV3BrickletFunction::WriteUid => 248,
123            ImuV3BrickletFunction::ReadUid => 249,
124            ImuV3BrickletFunction::GetIdentity => 255,
125            ImuV3BrickletFunction::CallbackAcceleration => 33,
126            ImuV3BrickletFunction::CallbackMagneticField => 34,
127            ImuV3BrickletFunction::CallbackAngularVelocity => 35,
128            ImuV3BrickletFunction::CallbackTemperature => 36,
129            ImuV3BrickletFunction::CallbackLinearAcceleration => 37,
130            ImuV3BrickletFunction::CallbackGravityVector => 38,
131            ImuV3BrickletFunction::CallbackOrientation => 39,
132            ImuV3BrickletFunction::CallbackQuaternion => 40,
133            ImuV3BrickletFunction::CallbackAllData => 41,
134        }
135    }
136}
137pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_2HZ: u8 = 0;
138pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_6HZ: u8 = 1;
139pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_8HZ: u8 = 2;
140pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_10HZ: u8 = 3;
141pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_15HZ: u8 = 4;
142pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_20HZ: u8 = 5;
143pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_25HZ: u8 = 6;
144pub const IMU_V3_BRICKLET_MAGNETOMETER_RATE_30HZ: u8 = 7;
145pub const IMU_V3_BRICKLET_GYROSCOPE_RANGE_2000DPS: u8 = 0;
146pub const IMU_V3_BRICKLET_GYROSCOPE_RANGE_1000DPS: u8 = 1;
147pub const IMU_V3_BRICKLET_GYROSCOPE_RANGE_500DPS: u8 = 2;
148pub const IMU_V3_BRICKLET_GYROSCOPE_RANGE_250DPS: u8 = 3;
149pub const IMU_V3_BRICKLET_GYROSCOPE_RANGE_125DPS: u8 = 4;
150pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_523HZ: u8 = 0;
151pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_230HZ: u8 = 1;
152pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_116HZ: u8 = 2;
153pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_47HZ: u8 = 3;
154pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_23HZ: u8 = 4;
155pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_12HZ: u8 = 5;
156pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_64HZ: u8 = 6;
157pub const IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_32HZ: u8 = 7;
158pub const IMU_V3_BRICKLET_ACCELEROMETER_RANGE_2G: u8 = 0;
159pub const IMU_V3_BRICKLET_ACCELEROMETER_RANGE_4G: u8 = 1;
160pub const IMU_V3_BRICKLET_ACCELEROMETER_RANGE_8G: u8 = 2;
161pub const IMU_V3_BRICKLET_ACCELEROMETER_RANGE_16G: u8 = 3;
162pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_7_81HZ: u8 = 0;
163pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_15_63HZ: u8 = 1;
164pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_31_25HZ: u8 = 2;
165pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_62_5HZ: u8 = 3;
166pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_125HZ: u8 = 4;
167pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_250HZ: u8 = 5;
168pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_500HZ: u8 = 6;
169pub const IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_1000HZ: u8 = 7;
170pub const IMU_V3_BRICKLET_SENSOR_FUSION_OFF: u8 = 0;
171pub const IMU_V3_BRICKLET_SENSOR_FUSION_ON: u8 = 1;
172pub const IMU_V3_BRICKLET_SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER: u8 = 2;
173pub const IMU_V3_BRICKLET_SENSOR_FUSION_ON_WITHOUT_FAST_MAGNETOMETER_CALIBRATION: u8 = 3;
174pub const IMU_V3_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
175pub const IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
176pub const IMU_V3_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
177pub const IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
178pub const IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
179pub const IMU_V3_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
180pub const IMU_V3_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
181pub const IMU_V3_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
182pub const IMU_V3_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
183pub const IMU_V3_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
184pub const IMU_V3_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
185pub const IMU_V3_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
186pub const IMU_V3_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
187pub const IMU_V3_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
188pub const IMU_V3_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
189
190#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
191pub struct Acceleration {
192    pub x: i16,
193    pub y: i16,
194    pub z: i16,
195}
196impl FromByteSlice for Acceleration {
197    fn bytes_expected() -> usize {
198        6
199    }
200    fn from_le_byte_slice(bytes: &[u8]) -> Acceleration {
201        Acceleration {
202            x: <i16>::from_le_byte_slice(&bytes[0..2]),
203            y: <i16>::from_le_byte_slice(&bytes[2..4]),
204            z: <i16>::from_le_byte_slice(&bytes[4..6]),
205        }
206    }
207}
208
209#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
210pub struct MagneticField {
211    pub x: i16,
212    pub y: i16,
213    pub z: i16,
214}
215impl FromByteSlice for MagneticField {
216    fn bytes_expected() -> usize {
217        6
218    }
219    fn from_le_byte_slice(bytes: &[u8]) -> MagneticField {
220        MagneticField {
221            x: <i16>::from_le_byte_slice(&bytes[0..2]),
222            y: <i16>::from_le_byte_slice(&bytes[2..4]),
223            z: <i16>::from_le_byte_slice(&bytes[4..6]),
224        }
225    }
226}
227
228#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
229pub struct AngularVelocity {
230    pub x: i16,
231    pub y: i16,
232    pub z: i16,
233}
234impl FromByteSlice for AngularVelocity {
235    fn bytes_expected() -> usize {
236        6
237    }
238    fn from_le_byte_slice(bytes: &[u8]) -> AngularVelocity {
239        AngularVelocity {
240            x: <i16>::from_le_byte_slice(&bytes[0..2]),
241            y: <i16>::from_le_byte_slice(&bytes[2..4]),
242            z: <i16>::from_le_byte_slice(&bytes[4..6]),
243        }
244    }
245}
246
247#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
248pub struct Orientation {
249    pub heading: i16,
250    pub roll: i16,
251    pub pitch: i16,
252}
253impl FromByteSlice for Orientation {
254    fn bytes_expected() -> usize {
255        6
256    }
257    fn from_le_byte_slice(bytes: &[u8]) -> Orientation {
258        Orientation {
259            heading: <i16>::from_le_byte_slice(&bytes[0..2]),
260            roll: <i16>::from_le_byte_slice(&bytes[2..4]),
261            pitch: <i16>::from_le_byte_slice(&bytes[4..6]),
262        }
263    }
264}
265
266#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
267pub struct LinearAcceleration {
268    pub x: i16,
269    pub y: i16,
270    pub z: i16,
271}
272impl FromByteSlice for LinearAcceleration {
273    fn bytes_expected() -> usize {
274        6
275    }
276    fn from_le_byte_slice(bytes: &[u8]) -> LinearAcceleration {
277        LinearAcceleration {
278            x: <i16>::from_le_byte_slice(&bytes[0..2]),
279            y: <i16>::from_le_byte_slice(&bytes[2..4]),
280            z: <i16>::from_le_byte_slice(&bytes[4..6]),
281        }
282    }
283}
284
285#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
286pub struct GravityVector {
287    pub x: i16,
288    pub y: i16,
289    pub z: i16,
290}
291impl FromByteSlice for GravityVector {
292    fn bytes_expected() -> usize {
293        6
294    }
295    fn from_le_byte_slice(bytes: &[u8]) -> GravityVector {
296        GravityVector {
297            x: <i16>::from_le_byte_slice(&bytes[0..2]),
298            y: <i16>::from_le_byte_slice(&bytes[2..4]),
299            z: <i16>::from_le_byte_slice(&bytes[4..6]),
300        }
301    }
302}
303
304#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
305pub struct Quaternion {
306    pub w: i16,
307    pub x: i16,
308    pub y: i16,
309    pub z: i16,
310}
311impl FromByteSlice for Quaternion {
312    fn bytes_expected() -> usize {
313        8
314    }
315    fn from_le_byte_slice(bytes: &[u8]) -> Quaternion {
316        Quaternion {
317            w: <i16>::from_le_byte_slice(&bytes[0..2]),
318            x: <i16>::from_le_byte_slice(&bytes[2..4]),
319            y: <i16>::from_le_byte_slice(&bytes[4..6]),
320            z: <i16>::from_le_byte_slice(&bytes[6..8]),
321        }
322    }
323}
324
325#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
326pub struct AllData {
327    pub acceleration: [i16; 3],
328    pub magnetic_field: [i16; 3],
329    pub angular_velocity: [i16; 3],
330    pub euler_angle: [i16; 3],
331    pub quaternion: [i16; 4],
332    pub linear_acceleration: [i16; 3],
333    pub gravity_vector: [i16; 3],
334    pub temperature: i8,
335    pub calibration_status: u8,
336}
337impl FromByteSlice for AllData {
338    fn bytes_expected() -> usize {
339        46
340    }
341    fn from_le_byte_slice(bytes: &[u8]) -> AllData {
342        AllData {
343            acceleration: <[i16; 3]>::from_le_byte_slice(&bytes[0..6]),
344            magnetic_field: <[i16; 3]>::from_le_byte_slice(&bytes[6..12]),
345            angular_velocity: <[i16; 3]>::from_le_byte_slice(&bytes[12..18]),
346            euler_angle: <[i16; 3]>::from_le_byte_slice(&bytes[18..24]),
347            quaternion: <[i16; 4]>::from_le_byte_slice(&bytes[24..32]),
348            linear_acceleration: <[i16; 3]>::from_le_byte_slice(&bytes[32..38]),
349            gravity_vector: <[i16; 3]>::from_le_byte_slice(&bytes[38..44]),
350            temperature: <i8>::from_le_byte_slice(&bytes[44..45]),
351            calibration_status: <u8>::from_le_byte_slice(&bytes[45..46]),
352        }
353    }
354}
355
356#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
357pub struct SensorConfiguration {
358    pub magnetometer_rate: u8,
359    pub gyroscope_range: u8,
360    pub gyroscope_bandwidth: u8,
361    pub accelerometer_range: u8,
362    pub accelerometer_bandwidth: u8,
363}
364impl FromByteSlice for SensorConfiguration {
365    fn bytes_expected() -> usize {
366        5
367    }
368    fn from_le_byte_slice(bytes: &[u8]) -> SensorConfiguration {
369        SensorConfiguration {
370            magnetometer_rate: <u8>::from_le_byte_slice(&bytes[0..1]),
371            gyroscope_range: <u8>::from_le_byte_slice(&bytes[1..2]),
372            gyroscope_bandwidth: <u8>::from_le_byte_slice(&bytes[2..3]),
373            accelerometer_range: <u8>::from_le_byte_slice(&bytes[3..4]),
374            accelerometer_bandwidth: <u8>::from_le_byte_slice(&bytes[4..5]),
375        }
376    }
377}
378
379#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
380pub struct AccelerationCallbackConfiguration {
381    pub period: u32,
382    pub value_has_to_change: bool,
383}
384impl FromByteSlice for AccelerationCallbackConfiguration {
385    fn bytes_expected() -> usize {
386        5
387    }
388    fn from_le_byte_slice(bytes: &[u8]) -> AccelerationCallbackConfiguration {
389        AccelerationCallbackConfiguration {
390            period: <u32>::from_le_byte_slice(&bytes[0..4]),
391            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
392        }
393    }
394}
395
396#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
397pub struct MagneticFieldCallbackConfiguration {
398    pub period: u32,
399    pub value_has_to_change: bool,
400}
401impl FromByteSlice for MagneticFieldCallbackConfiguration {
402    fn bytes_expected() -> usize {
403        5
404    }
405    fn from_le_byte_slice(bytes: &[u8]) -> MagneticFieldCallbackConfiguration {
406        MagneticFieldCallbackConfiguration {
407            period: <u32>::from_le_byte_slice(&bytes[0..4]),
408            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
409        }
410    }
411}
412
413#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
414pub struct AngularVelocityCallbackConfiguration {
415    pub period: u32,
416    pub value_has_to_change: bool,
417}
418impl FromByteSlice for AngularVelocityCallbackConfiguration {
419    fn bytes_expected() -> usize {
420        5
421    }
422    fn from_le_byte_slice(bytes: &[u8]) -> AngularVelocityCallbackConfiguration {
423        AngularVelocityCallbackConfiguration {
424            period: <u32>::from_le_byte_slice(&bytes[0..4]),
425            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
426        }
427    }
428}
429
430#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
431pub struct TemperatureCallbackConfiguration {
432    pub period: u32,
433    pub value_has_to_change: bool,
434}
435impl FromByteSlice for TemperatureCallbackConfiguration {
436    fn bytes_expected() -> usize {
437        5
438    }
439    fn from_le_byte_slice(bytes: &[u8]) -> TemperatureCallbackConfiguration {
440        TemperatureCallbackConfiguration {
441            period: <u32>::from_le_byte_slice(&bytes[0..4]),
442            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
443        }
444    }
445}
446
447#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
448pub struct OrientationCallbackConfiguration {
449    pub period: u32,
450    pub value_has_to_change: bool,
451}
452impl FromByteSlice for OrientationCallbackConfiguration {
453    fn bytes_expected() -> usize {
454        5
455    }
456    fn from_le_byte_slice(bytes: &[u8]) -> OrientationCallbackConfiguration {
457        OrientationCallbackConfiguration {
458            period: <u32>::from_le_byte_slice(&bytes[0..4]),
459            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
460        }
461    }
462}
463
464#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
465pub struct LinearAccelerationCallbackConfiguration {
466    pub period: u32,
467    pub value_has_to_change: bool,
468}
469impl FromByteSlice for LinearAccelerationCallbackConfiguration {
470    fn bytes_expected() -> usize {
471        5
472    }
473    fn from_le_byte_slice(bytes: &[u8]) -> LinearAccelerationCallbackConfiguration {
474        LinearAccelerationCallbackConfiguration {
475            period: <u32>::from_le_byte_slice(&bytes[0..4]),
476            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
477        }
478    }
479}
480
481#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
482pub struct GravityVectorCallbackConfiguration {
483    pub period: u32,
484    pub value_has_to_change: bool,
485}
486impl FromByteSlice for GravityVectorCallbackConfiguration {
487    fn bytes_expected() -> usize {
488        5
489    }
490    fn from_le_byte_slice(bytes: &[u8]) -> GravityVectorCallbackConfiguration {
491        GravityVectorCallbackConfiguration {
492            period: <u32>::from_le_byte_slice(&bytes[0..4]),
493            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
494        }
495    }
496}
497
498#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
499pub struct QuaternionCallbackConfiguration {
500    pub period: u32,
501    pub value_has_to_change: bool,
502}
503impl FromByteSlice for QuaternionCallbackConfiguration {
504    fn bytes_expected() -> usize {
505        5
506    }
507    fn from_le_byte_slice(bytes: &[u8]) -> QuaternionCallbackConfiguration {
508        QuaternionCallbackConfiguration {
509            period: <u32>::from_le_byte_slice(&bytes[0..4]),
510            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
511        }
512    }
513}
514
515#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
516pub struct AllDataCallbackConfiguration {
517    pub period: u32,
518    pub value_has_to_change: bool,
519}
520impl FromByteSlice for AllDataCallbackConfiguration {
521    fn bytes_expected() -> usize {
522        5
523    }
524    fn from_le_byte_slice(bytes: &[u8]) -> AllDataCallbackConfiguration {
525        AllDataCallbackConfiguration {
526            period: <u32>::from_le_byte_slice(&bytes[0..4]),
527            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
528        }
529    }
530}
531
532#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
533pub struct AccelerationEvent {
534    pub x: i16,
535    pub y: i16,
536    pub z: i16,
537}
538impl FromByteSlice for AccelerationEvent {
539    fn bytes_expected() -> usize {
540        6
541    }
542    fn from_le_byte_slice(bytes: &[u8]) -> AccelerationEvent {
543        AccelerationEvent {
544            x: <i16>::from_le_byte_slice(&bytes[0..2]),
545            y: <i16>::from_le_byte_slice(&bytes[2..4]),
546            z: <i16>::from_le_byte_slice(&bytes[4..6]),
547        }
548    }
549}
550
551#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
552pub struct MagneticFieldEvent {
553    pub x: i16,
554    pub y: i16,
555    pub z: i16,
556}
557impl FromByteSlice for MagneticFieldEvent {
558    fn bytes_expected() -> usize {
559        6
560    }
561    fn from_le_byte_slice(bytes: &[u8]) -> MagneticFieldEvent {
562        MagneticFieldEvent {
563            x: <i16>::from_le_byte_slice(&bytes[0..2]),
564            y: <i16>::from_le_byte_slice(&bytes[2..4]),
565            z: <i16>::from_le_byte_slice(&bytes[4..6]),
566        }
567    }
568}
569
570#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
571pub struct AngularVelocityEvent {
572    pub x: i16,
573    pub y: i16,
574    pub z: i16,
575}
576impl FromByteSlice for AngularVelocityEvent {
577    fn bytes_expected() -> usize {
578        6
579    }
580    fn from_le_byte_slice(bytes: &[u8]) -> AngularVelocityEvent {
581        AngularVelocityEvent {
582            x: <i16>::from_le_byte_slice(&bytes[0..2]),
583            y: <i16>::from_le_byte_slice(&bytes[2..4]),
584            z: <i16>::from_le_byte_slice(&bytes[4..6]),
585        }
586    }
587}
588
589#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
590pub struct LinearAccelerationEvent {
591    pub x: i16,
592    pub y: i16,
593    pub z: i16,
594}
595impl FromByteSlice for LinearAccelerationEvent {
596    fn bytes_expected() -> usize {
597        6
598    }
599    fn from_le_byte_slice(bytes: &[u8]) -> LinearAccelerationEvent {
600        LinearAccelerationEvent {
601            x: <i16>::from_le_byte_slice(&bytes[0..2]),
602            y: <i16>::from_le_byte_slice(&bytes[2..4]),
603            z: <i16>::from_le_byte_slice(&bytes[4..6]),
604        }
605    }
606}
607
608#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
609pub struct GravityVectorEvent {
610    pub x: i16,
611    pub y: i16,
612    pub z: i16,
613}
614impl FromByteSlice for GravityVectorEvent {
615    fn bytes_expected() -> usize {
616        6
617    }
618    fn from_le_byte_slice(bytes: &[u8]) -> GravityVectorEvent {
619        GravityVectorEvent {
620            x: <i16>::from_le_byte_slice(&bytes[0..2]),
621            y: <i16>::from_le_byte_slice(&bytes[2..4]),
622            z: <i16>::from_le_byte_slice(&bytes[4..6]),
623        }
624    }
625}
626
627#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
628pub struct OrientationEvent {
629    pub heading: i16,
630    pub roll: i16,
631    pub pitch: i16,
632}
633impl FromByteSlice for OrientationEvent {
634    fn bytes_expected() -> usize {
635        6
636    }
637    fn from_le_byte_slice(bytes: &[u8]) -> OrientationEvent {
638        OrientationEvent {
639            heading: <i16>::from_le_byte_slice(&bytes[0..2]),
640            roll: <i16>::from_le_byte_slice(&bytes[2..4]),
641            pitch: <i16>::from_le_byte_slice(&bytes[4..6]),
642        }
643    }
644}
645
646#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
647pub struct QuaternionEvent {
648    pub w: i16,
649    pub x: i16,
650    pub y: i16,
651    pub z: i16,
652}
653impl FromByteSlice for QuaternionEvent {
654    fn bytes_expected() -> usize {
655        8
656    }
657    fn from_le_byte_slice(bytes: &[u8]) -> QuaternionEvent {
658        QuaternionEvent {
659            w: <i16>::from_le_byte_slice(&bytes[0..2]),
660            x: <i16>::from_le_byte_slice(&bytes[2..4]),
661            y: <i16>::from_le_byte_slice(&bytes[4..6]),
662            z: <i16>::from_le_byte_slice(&bytes[6..8]),
663        }
664    }
665}
666
667#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
668pub struct AllDataEvent {
669    pub acceleration: [i16; 3],
670    pub magnetic_field: [i16; 3],
671    pub angular_velocity: [i16; 3],
672    pub euler_angle: [i16; 3],
673    pub quaternion: [i16; 4],
674    pub linear_acceleration: [i16; 3],
675    pub gravity_vector: [i16; 3],
676    pub temperature: i8,
677    pub calibration_status: u8,
678}
679impl FromByteSlice for AllDataEvent {
680    fn bytes_expected() -> usize {
681        46
682    }
683    fn from_le_byte_slice(bytes: &[u8]) -> AllDataEvent {
684        AllDataEvent {
685            acceleration: <[i16; 3]>::from_le_byte_slice(&bytes[0..6]),
686            magnetic_field: <[i16; 3]>::from_le_byte_slice(&bytes[6..12]),
687            angular_velocity: <[i16; 3]>::from_le_byte_slice(&bytes[12..18]),
688            euler_angle: <[i16; 3]>::from_le_byte_slice(&bytes[18..24]),
689            quaternion: <[i16; 4]>::from_le_byte_slice(&bytes[24..32]),
690            linear_acceleration: <[i16; 3]>::from_le_byte_slice(&bytes[32..38]),
691            gravity_vector: <[i16; 3]>::from_le_byte_slice(&bytes[38..44]),
692            temperature: <i8>::from_le_byte_slice(&bytes[44..45]),
693            calibration_status: <u8>::from_le_byte_slice(&bytes[45..46]),
694        }
695    }
696}
697
698#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
699pub struct SpitfpErrorCount {
700    pub error_count_ack_checksum: u32,
701    pub error_count_message_checksum: u32,
702    pub error_count_frame: u32,
703    pub error_count_overflow: u32,
704}
705impl FromByteSlice for SpitfpErrorCount {
706    fn bytes_expected() -> usize {
707        16
708    }
709    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
710        SpitfpErrorCount {
711            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
712            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
713            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
714            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
715        }
716    }
717}
718
719#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
720pub struct Identity {
721    pub uid: String,
722    pub connected_uid: String,
723    pub position: char,
724    pub hardware_version: [u8; 3],
725    pub firmware_version: [u8; 3],
726    pub device_identifier: u16,
727}
728impl FromByteSlice for Identity {
729    fn bytes_expected() -> usize {
730        25
731    }
732    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
733        Identity {
734            uid: <String>::from_le_byte_slice(&bytes[0..8]),
735            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
736            position: <char>::from_le_byte_slice(&bytes[16..17]),
737            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
738            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
739            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
740        }
741    }
742}
743
744/// Full fledged AHRS with 9 degrees of freedom
745#[derive(Clone)]
746pub struct ImuV3Bricklet {
747    device: Device,
748}
749impl ImuV3Bricklet {
750    pub const DEVICE_IDENTIFIER: u16 = 2161;
751    pub const DEVICE_DISPLAY_NAME: &'static str = "IMU Bricklet 3.0";
752    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
753    pub fn new(uid: Uid, connection: AsyncIpConnection) -> ImuV3Bricklet {
754        let mut result = ImuV3Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
755        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetAcceleration) as usize] = ResponseExpectedFlag::AlwaysTrue;
756        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetMagneticField) as usize] = ResponseExpectedFlag::AlwaysTrue;
757        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetAngularVelocity) as usize] = ResponseExpectedFlag::AlwaysTrue;
758        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
759        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetOrientation) as usize] = ResponseExpectedFlag::AlwaysTrue;
760        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetLinearAcceleration) as usize] = ResponseExpectedFlag::AlwaysTrue;
761        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetGravityVector) as usize] = ResponseExpectedFlag::AlwaysTrue;
762        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetQuaternion) as usize] = ResponseExpectedFlag::AlwaysTrue;
763        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetAllData) as usize] = ResponseExpectedFlag::AlwaysTrue;
764        result.device.response_expected[u8::from(ImuV3BrickletFunction::SaveCalibration) as usize] = ResponseExpectedFlag::AlwaysTrue;
765        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetSensorConfiguration) as usize] = ResponseExpectedFlag::False;
766        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetSensorConfiguration) as usize] =
767            ResponseExpectedFlag::AlwaysTrue;
768        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetSensorFusionMode) as usize] = ResponseExpectedFlag::False;
769        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetSensorFusionMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
770        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetAccelerationCallbackConfiguration) as usize] =
771            ResponseExpectedFlag::True;
772        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetAccelerationCallbackConfiguration) as usize] =
773            ResponseExpectedFlag::AlwaysTrue;
774        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetMagneticFieldCallbackConfiguration) as usize] =
775            ResponseExpectedFlag::True;
776        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetMagneticFieldCallbackConfiguration) as usize] =
777            ResponseExpectedFlag::AlwaysTrue;
778        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetAngularVelocityCallbackConfiguration) as usize] =
779            ResponseExpectedFlag::True;
780        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetAngularVelocityCallbackConfiguration) as usize] =
781            ResponseExpectedFlag::AlwaysTrue;
782        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetTemperatureCallbackConfiguration) as usize] =
783            ResponseExpectedFlag::True;
784        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetTemperatureCallbackConfiguration) as usize] =
785            ResponseExpectedFlag::AlwaysTrue;
786        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetOrientationCallbackConfiguration) as usize] =
787            ResponseExpectedFlag::True;
788        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetOrientationCallbackConfiguration) as usize] =
789            ResponseExpectedFlag::AlwaysTrue;
790        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetLinearAccelerationCallbackConfiguration) as usize] =
791            ResponseExpectedFlag::True;
792        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetLinearAccelerationCallbackConfiguration) as usize] =
793            ResponseExpectedFlag::AlwaysTrue;
794        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetGravityVectorCallbackConfiguration) as usize] =
795            ResponseExpectedFlag::True;
796        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetGravityVectorCallbackConfiguration) as usize] =
797            ResponseExpectedFlag::AlwaysTrue;
798        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetQuaternionCallbackConfiguration) as usize] =
799            ResponseExpectedFlag::True;
800        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetQuaternionCallbackConfiguration) as usize] =
801            ResponseExpectedFlag::AlwaysTrue;
802        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetAllDataCallbackConfiguration) as usize] =
803            ResponseExpectedFlag::True;
804        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetAllDataCallbackConfiguration) as usize] =
805            ResponseExpectedFlag::AlwaysTrue;
806        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
807        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
808        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
809        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetWriteFirmwarePointer) as usize] = ResponseExpectedFlag::False;
810        result.device.response_expected[u8::from(ImuV3BrickletFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
811        result.device.response_expected[u8::from(ImuV3BrickletFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
812        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetStatusLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
813        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
814        result.device.response_expected[u8::from(ImuV3BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
815        result.device.response_expected[u8::from(ImuV3BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
816        result.device.response_expected[u8::from(ImuV3BrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
817        result.device.response_expected[u8::from(ImuV3BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
818        result
819    }
820
821    /// Returns the response expected flag for the function specified by the function ID parameter.
822    /// It is true if the function is expected to send a response, false otherwise.
823    ///
824    /// For getter functions this is enabled by default and cannot be disabled, because those
825    /// functions will always send a response. For callback configuration functions it is enabled
826    /// by default too, but can be disabled by [`set_response_expected`](crate::imu_v3_bricklet::ImuV3Bricklet::set_response_expected).
827    /// For setter functions it is disabled by default and can be enabled.
828    ///
829    /// Enabling the response expected flag for a setter function allows to detect timeouts
830    /// and other error conditions calls of this setter as well. The device will then send a response
831    /// for this purpose. If this flag is disabled for a setter function then no response is sent
832    /// and errors are silently ignored, because they cannot be detected.
833    ///
834    /// See [`set_response_expected`](crate::imu_v3_bricklet::ImuV3Bricklet::set_response_expected) for the list of function ID constants available for this function.
835    pub fn get_response_expected(&mut self, fun: ImuV3BrickletFunction) -> Result<bool, GetResponseExpectedError> {
836        self.device.get_response_expected(u8::from(fun))
837    }
838
839    /// Changes the response expected flag of the function specified by the function ID parameter.
840    /// This flag can only be changed for setter (default value: false) and callback configuration
841    /// functions (default value: true). For getter functions it is always enabled.
842    ///
843    /// Enabling the response expected flag for a setter function allows to detect timeouts and
844    /// other error conditions calls of this setter as well. The device will then send a response
845    /// for this purpose. If this flag is disabled for a setter function then no response is sent
846    /// and errors are silently ignored, because they cannot be detected.
847    pub fn set_response_expected(&mut self, fun: ImuV3BrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
848        self.device.set_response_expected(u8::from(fun), response_expected)
849    }
850
851    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
852    pub fn set_response_expected_all(&mut self, response_expected: bool) {
853        self.device.set_response_expected_all(response_expected)
854    }
855
856    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
857    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
858    pub fn get_api_version(&self) -> [u8; 3] {
859        self.device.api_version
860    }
861
862    /// This receiver is triggered periodically with the period that is set by
863    /// [`set_acceleration_callback_configuration`]. The parameters are the acceleration
864    /// for the x, y and z axis.
865    ///
866    /// [`set_acceleration_callback_configuration`]: #method.set_acceleration_callback_configuration
867    pub async fn get_acceleration_callback_receiver(&mut self) -> impl Stream<Item = AccelerationEvent> {
868        self.device
869            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackAcceleration))
870            .await
871            .map(|p| AccelerationEvent::from_le_byte_slice(p.body()))
872    }
873
874    /// This receiver is triggered periodically with the period that is set by
875    /// [`set_magnetic_field_callback_configuration`]. The parameters are the magnetic
876    /// field for the x, y and z axis.
877    pub async fn get_magnetic_field_callback_receiver(&mut self) -> impl Stream<Item = MagneticFieldEvent> {
878        self.device
879            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackMagneticField))
880            .await
881            .map(|p| MagneticFieldEvent::from_le_byte_slice(p.body()))
882    }
883
884    /// This receiver is triggered periodically with the period that is set by
885    /// [`set_angular_velocity_callback_configuration`]. The parameters are the angular
886    /// velocity for the x, y and z axis.
887    pub async fn get_angular_velocity_callback_receiver(&mut self) -> impl Stream<Item = AngularVelocityEvent> {
888        self.device
889            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackAngularVelocity))
890            .await
891            .map(|p| AngularVelocityEvent::from_le_byte_slice(p.body()))
892    }
893
894    /// This receiver is triggered periodically with the period that is set by
895    /// [`set_temperature_callback_configuration`]. The parameter is the temperature.
896    pub async fn get_temperature_callback_receiver(&mut self) -> impl Stream<Item = i8> {
897        self.device
898            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackTemperature))
899            .await
900            .map(|p| i8::from_le_byte_slice(p.body()))
901    }
902
903    /// This receiver is triggered periodically with the period that is set by
904    /// [`set_linear_acceleration_callback_configuration`]. The parameters are the
905    /// linear acceleration for the x, y and z axis.
906    pub async fn get_linear_acceleration_callback_receiver(&mut self) -> impl Stream<Item = LinearAccelerationEvent> {
907        self.device
908            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackLinearAcceleration))
909            .await
910            .map(|p| LinearAccelerationEvent::from_le_byte_slice(p.body()))
911    }
912
913    /// This receiver is triggered periodically with the period that is set by
914    /// [`set_gravity_vector_callback_configuration`]. The parameters gravity vector
915    /// for the x, y and z axis.
916    pub async fn get_gravity_vector_callback_receiver(&mut self) -> impl Stream<Item = GravityVectorEvent> {
917        self.device
918            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackGravityVector))
919            .await
920            .map(|p| GravityVectorEvent::from_le_byte_slice(p.body()))
921    }
922
923    /// This receiver is triggered periodically with the period that is set by
924    /// [`set_orientation_callback_configuration`]. The parameters are the orientation
925    /// (heading (yaw), roll, pitch) of the IMU Brick in Euler angles. See
926    /// [`get_orientation`] for details.
927    pub async fn get_orientation_callback_receiver(&mut self) -> impl Stream<Item = OrientationEvent> {
928        self.device
929            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackOrientation))
930            .await
931            .map(|p| OrientationEvent::from_le_byte_slice(p.body()))
932    }
933
934    /// This receiver is triggered periodically with the period that is set by
935    /// [`set_quaternion_callback_configuration`]. The parameters are the orientation
936    /// (w, x, y, z) of the IMU Brick in quaternions. See [`get_quaternion`]
937    /// for details.
938    pub async fn get_quaternion_callback_receiver(&mut self) -> impl Stream<Item = QuaternionEvent> {
939        self.device
940            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackQuaternion))
941            .await
942            .map(|p| QuaternionEvent::from_le_byte_slice(p.body()))
943    }
944
945    /// This receiver is triggered periodically with the period that is set by
946    /// [`set_all_data_callback_configuration`]. The parameters are as for
947    /// [`get_all_data`].
948    pub async fn get_all_data_callback_receiver(&mut self) -> impl Stream<Item = AllDataEvent> {
949        self.device
950            .get_callback_receiver(u8::from(ImuV3BrickletFunction::CallbackAllData))
951            .await
952            .map(|p| AllDataEvent::from_le_byte_slice(p.body()))
953    }
954
955    /// Returns the calibrated acceleration from the accelerometer for the
956    /// x, y and z axis. The acceleration is in the range configured with
957    /// [`set_sensor_configuration`].
958    ///
959    /// If you want to get the acceleration periodically, it is recommended
960    /// to use the [`get_acceleration_callback_receiver`] receiver and set the period with
961    /// [`set_acceleration_callback_configuration`].
962    pub async fn get_acceleration(&mut self) -> Result<Acceleration, TinkerforgeError> {
963        let payload = [0; 0];
964
965        #[allow(unused_variables)]
966        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetAcceleration), &payload).await?;
967        Ok(Acceleration::from_le_byte_slice(result.body()))
968    }
969
970    /// Returns the calibrated magnetic field from the magnetometer for the
971    /// x, y and z axis.
972    ///
973    /// If you want to get the magnetic field periodically, it is recommended
974    /// to use the [`get_magnetic_field_callback_receiver`] receiver and set the period with
975    /// [`set_magnetic_field_callback_configuration`].
976    pub async fn get_magnetic_field(&mut self) -> Result<MagneticField, TinkerforgeError> {
977        let payload = [0; 0];
978
979        #[allow(unused_variables)]
980        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetMagneticField), &payload).await?;
981        Ok(MagneticField::from_le_byte_slice(result.body()))
982    }
983
984    /// Returns the calibrated angular velocity from the gyroscope for the
985    /// x, y and z axis. The angular velocity is in the range configured with
986    /// [`set_sensor_configuration`].
987    ///
988    /// If you want to get the angular velocity periodically, it is recommended
989    /// to use the [`get_angular_velocity_callback_receiver`] areceiver nd set the period with
990    /// [`set_angular_velocity_callback_configuration`].
991    pub async fn get_angular_velocity(&mut self) -> Result<AngularVelocity, TinkerforgeError> {
992        let payload = [0; 0];
993
994        #[allow(unused_variables)]
995        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetAngularVelocity), &payload).await?;
996        Ok(AngularVelocity::from_le_byte_slice(result.body()))
997    }
998
999    /// Returns the temperature of the IMU Brick.
1000    /// The temperature is measured in the core of the BNO055 IC, it is not the
1001    /// ambient temperature
1002    pub async fn get_temperature(&mut self) -> Result<i8, TinkerforgeError> {
1003        let payload = [0; 0];
1004
1005        #[allow(unused_variables)]
1006        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetTemperature), &payload).await?;
1007        Ok(i8::from_le_byte_slice(result.body()))
1008    }
1009
1010    /// Returns the current orientation (heading, roll, pitch) of the IMU Brick as
1011    /// independent Euler angles. Note that Euler angles always
1012    /// experience a [gimbal lock](https://en.wikipedia.org/wiki/Gimbal_lock)__.
1013    /// We recommend that you use quaternions instead, if you need the absolute
1014    /// orientation.
1015    ///
1016    /// If you want to get the orientation periodically, it is recommended
1017    /// to use the [`get_orientation_callback_receiver`] receiver and set the period with
1018    /// [`set_orientation_callback_configuration`].
1019    pub async fn get_orientation(&mut self) -> Result<Orientation, TinkerforgeError> {
1020        let payload = [0; 0];
1021
1022        #[allow(unused_variables)]
1023        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetOrientation), &payload).await?;
1024        Ok(Orientation::from_le_byte_slice(result.body()))
1025    }
1026
1027    /// Returns the linear acceleration of the IMU Brick for the
1028    /// x, y and z axis. The acceleration is in the range configured with
1029    /// [`set_sensor_configuration`].
1030    ///
1031    /// The linear acceleration is the acceleration in each of the three
1032    /// axis of the IMU Brick with the influences of gravity removed.
1033    ///
1034    /// It is also possible to get the gravity vector with the influence of linear
1035    /// acceleration removed, see [`get_gravity_vector`].
1036    ///
1037    /// If you want to get the linear acceleration periodically, it is recommended
1038    /// to use the [`get_linear_acceleration_callback_receiver`] receiver and set the period with
1039    /// [`set_linear_acceleration_callback_configuration`].
1040    pub async fn get_linear_acceleration(&mut self) -> Result<LinearAcceleration, TinkerforgeError> {
1041        let payload = [0; 0];
1042
1043        #[allow(unused_variables)]
1044        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetLinearAcceleration), &payload).await?;
1045        Ok(LinearAcceleration::from_le_byte_slice(result.body()))
1046    }
1047
1048    /// Returns the current gravity vector of the IMU Brick for the
1049    /// x, y and z axis.
1050    ///
1051    /// The gravity vector is the acceleration that occurs due to gravity.
1052    /// Influences of additional linear acceleration are removed.
1053    ///
1054    /// It is also possible to get the linear acceleration with the influence
1055    /// of gravity removed, see [`get_linear_acceleration`].
1056    ///
1057    /// If you want to get the gravity vector periodically, it is recommended
1058    /// to use the [`get_gravity_vector_callback_receiver`] receiver and set the period with
1059    /// [`set_gravity_vector_callback_configuration`].
1060    pub async fn get_gravity_vector(&mut self) -> Result<GravityVector, TinkerforgeError> {
1061        let payload = [0; 0];
1062
1063        #[allow(unused_variables)]
1064        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetGravityVector), &payload).await?;
1065        Ok(GravityVector::from_le_byte_slice(result.body()))
1066    }
1067
1068    /// Returns the current orientation (w, x, y, z) of the IMU Brick as
1069    /// [quaternions](https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation)__.
1070    ///
1071    /// You have to divide the return values by 16383 (14 bit) to get
1072    /// the usual range of -1.0 to +1.0 for quaternions.
1073    ///
1074    /// If you want to get the quaternions periodically, it is recommended
1075    /// to use the [`get_quaternion_callback_receiver`] receiver and set the period with
1076    /// [`set_quaternion_callback_configuration`].
1077    pub async fn get_quaternion(&mut self) -> Result<Quaternion, TinkerforgeError> {
1078        let payload = [0; 0];
1079
1080        #[allow(unused_variables)]
1081        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetQuaternion), &payload).await?;
1082        Ok(Quaternion::from_le_byte_slice(result.body()))
1083    }
1084
1085    /// Return all of the available data of the IMU Brick.
1086    ///
1087    /// * acceleration (see [`get_acceleration`])
1088    /// * magnetic field (see [`get_magnetic_field`])
1089    /// * angular velocity (see [`get_angular_velocity`])
1090    /// * Euler angles (see [`get_orientation`])
1091    /// * quaternion (see [`get_quaternion`])
1092    /// * linear acceleration (see [`get_linear_acceleration`])
1093    /// * gravity vector (see [`get_gravity_vector`])
1094    /// * temperature (see [`get_temperature`])
1095    /// * calibration status (see below)
1096    ///
1097    /// The calibration status consists of four pairs of two bits. Each pair
1098    /// of bits represents the status of the current calibration.
1099    ///
1100    /// * bit 0-1: Magnetometer
1101    /// * bit 2-3: Accelerometer
1102    /// * bit 4-5: Gyroscope
1103    /// * bit 6-7: System
1104    ///
1105    /// A value of 0 means for not calibrated and a value of 3 means
1106    /// fully calibrated. In your program you should always be able to
1107    /// ignore the calibration status, it is used by the calibration
1108    /// window of the Brick Viewer and it can be ignored after the first
1109    /// calibration. See the documentation in the calibration window for
1110    /// more information regarding the calibration of the IMU Brick.
1111    ///
1112    /// If you want to get the data periodically, it is recommended
1113    /// to use the [`get_all_data_callback_receiver`] receiver and set the period with
1114    /// [`set_all_data_callback_configuration`].
1115    pub async fn get_all_data(&mut self) -> Result<AllData, TinkerforgeError> {
1116        let payload = [0; 0];
1117
1118        #[allow(unused_variables)]
1119        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetAllData), &payload).await?;
1120        Ok(AllData::from_le_byte_slice(result.body()))
1121    }
1122
1123    /// A call of this function saves the current calibration to be used
1124    /// as a starting point for the next restart of continuous calibration
1125    /// of the IMU Brick.
1126    ///
1127    /// A return value of *true* means that the calibration could be used and
1128    /// *false* means that it could not be used (this happens if the calibration
1129    /// status is not fully calibrated).
1130    ///
1131    /// This function is used by the calibration window of the Brick Viewer, you
1132    /// should not need to call it in your program.
1133    pub async fn save_calibration(&mut self) -> Result<bool, TinkerforgeError> {
1134        let payload = [0; 0];
1135
1136        #[allow(unused_variables)]
1137        let result = self.device.get(u8::from(ImuV3BrickletFunction::SaveCalibration), &payload).await?;
1138        Ok(bool::from_le_byte_slice(result.body()))
1139    }
1140
1141    /// Sets the available sensor configuration for the Magnetometer, Gyroscope and
1142    /// Accelerometer. The Accelerometer Range is user selectable in all fusion modes,
1143    /// all other configurations are auto-controlled in fusion mode.
1144    ///
1145    /// Associated constants:
1146    /// * IMU_V3_BRICKLET_MAGNETOMETER_RATE_2HZ
1147    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_6HZ
1148    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_8HZ
1149    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_10HZ
1150    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_15HZ
1151    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_20HZ
1152    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_25HZ
1153    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_30HZ
1154    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_2000DPS
1155    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_1000DPS
1156    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_500DPS
1157    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_250DPS
1158    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_125DPS
1159    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_523HZ
1160    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_230HZ
1161    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_116HZ
1162    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_47HZ
1163    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_23HZ
1164    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_12HZ
1165    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_64HZ
1166    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_32HZ
1167    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_2G
1168    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_4G
1169    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_8G
1170    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_16G
1171    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_7_81HZ
1172    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_15_63HZ
1173    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_31_25HZ
1174    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_62_5HZ
1175    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_125HZ
1176    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_250HZ
1177    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_500HZ
1178    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_1000HZ
1179    pub async fn set_sensor_configuration(
1180        &mut self,
1181        magnetometer_rate: u8,
1182        gyroscope_range: u8,
1183        gyroscope_bandwidth: u8,
1184        accelerometer_range: u8,
1185        accelerometer_bandwidth: u8,
1186    ) -> Result<(), TinkerforgeError> {
1187        let mut payload = [0; 5];
1188        magnetometer_rate.write_to_slice(&mut payload[0..1]);
1189        gyroscope_range.write_to_slice(&mut payload[1..2]);
1190        gyroscope_bandwidth.write_to_slice(&mut payload[2..3]);
1191        accelerometer_range.write_to_slice(&mut payload[3..4]);
1192        accelerometer_bandwidth.write_to_slice(&mut payload[4..5]);
1193
1194        #[allow(unused_variables)]
1195        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetSensorConfiguration), &payload).await?;
1196        Ok(())
1197    }
1198
1199    /// Returns the sensor configuration as set by [`set_sensor_configuration`].
1200    ///
1201    /// Associated constants:
1202    /// * IMU_V3_BRICKLET_MAGNETOMETER_RATE_2HZ
1203    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_6HZ
1204    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_8HZ
1205    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_10HZ
1206    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_15HZ
1207    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_20HZ
1208    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_25HZ
1209    ///	* IMU_V3_BRICKLET_MAGNETOMETER_RATE_30HZ
1210    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_2000DPS
1211    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_1000DPS
1212    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_500DPS
1213    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_250DPS
1214    ///	* IMU_V3_BRICKLET_GYROSCOPE_RANGE_125DPS
1215    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_523HZ
1216    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_230HZ
1217    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_116HZ
1218    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_47HZ
1219    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_23HZ
1220    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_12HZ
1221    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_64HZ
1222    ///	* IMU_V3_BRICKLET_GYROSCOPE_BANDWIDTH_32HZ
1223    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_2G
1224    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_4G
1225    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_8G
1226    ///	* IMU_V3_BRICKLET_ACCELEROMETER_RANGE_16G
1227    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_7_81HZ
1228    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_15_63HZ
1229    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_31_25HZ
1230    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_62_5HZ
1231    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_125HZ
1232    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_250HZ
1233    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_500HZ
1234    ///	* IMU_V3_BRICKLET_ACCELEROMETER_BANDWIDTH_1000HZ
1235    pub async fn get_sensor_configuration(&mut self) -> Result<SensorConfiguration, TinkerforgeError> {
1236        let payload = [0; 0];
1237
1238        #[allow(unused_variables)]
1239        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetSensorConfiguration), &payload).await?;
1240        Ok(SensorConfiguration::from_le_byte_slice(result.body()))
1241    }
1242
1243    /// If the fusion mode is turned off, the functions [`get_acceleration`],
1244    /// [`get_magnetic_field`] and [`get_angular_velocity`] return uncalibrated
1245    /// and uncompensated sensor data. All other sensor data getters return no data.
1246    ///
1247    /// Since firmware version 2.0.6 you can also use a fusion mode without magnetometer.
1248    /// In this mode the calculated orientation is relative (with magnetometer it is
1249    /// absolute with respect to the earth). However, the calculation can't be influenced
1250    /// by spurious magnetic fields.
1251    ///
1252    /// Since firmware version 2.0.13 you can also use a fusion mode without fast
1253    /// magnetometer calibration. This mode is the same as the normal fusion mode,
1254    /// but the fast magnetometer calibration is turned off. So to find the orientation
1255    /// the first time will likely take longer, but small magnetic influences might
1256    /// not affect the automatic calibration as much.
1257    ///
1258    /// Associated constants:
1259    /// * IMU_V3_BRICKLET_SENSOR_FUSION_OFF
1260    ///	* IMU_V3_BRICKLET_SENSOR_FUSION_ON
1261    ///	* IMU_V3_BRICKLET_SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER
1262    ///	* IMU_V3_BRICKLET_SENSOR_FUSION_ON_WITHOUT_FAST_MAGNETOMETER_CALIBRATION
1263    pub async fn set_sensor_fusion_mode(&mut self, mode: u8) -> Result<(), TinkerforgeError> {
1264        let mut payload = [0; 1];
1265        mode.write_to_slice(&mut payload[0..1]);
1266
1267        #[allow(unused_variables)]
1268        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetSensorFusionMode), &payload).await?;
1269        Ok(())
1270    }
1271
1272    /// Returns the sensor fusion mode as set by [`set_sensor_fusion_mode`].
1273    ///
1274    /// Associated constants:
1275    /// * IMU_V3_BRICKLET_SENSOR_FUSION_OFF
1276    ///	* IMU_V3_BRICKLET_SENSOR_FUSION_ON
1277    ///	* IMU_V3_BRICKLET_SENSOR_FUSION_ON_WITHOUT_MAGNETOMETER
1278    ///	* IMU_V3_BRICKLET_SENSOR_FUSION_ON_WITHOUT_FAST_MAGNETOMETER_CALIBRATION
1279    pub async fn get_sensor_fusion_mode(&mut self) -> Result<u8, TinkerforgeError> {
1280        let payload = [0; 0];
1281
1282        #[allow(unused_variables)]
1283        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetSensorFusionMode), &payload).await?;
1284        Ok(u8::from_le_byte_slice(result.body()))
1285    }
1286
1287    /// The period is the period with which the [`get_acceleration_callback_receiver`] receiver
1288    /// is triggered periodically. A value of 0 turns the receiver off.
1289    ///
1290    /// If the `value has to change`-parameter is set to true, the receiver is only
1291    /// triggered after the value has changed. If the value didn't change within the
1292    /// period, the receiver is triggered immediately on change.
1293    ///
1294    /// If it is set to false, the receiver is continuously triggered with the period,
1295    /// independent of the value.
1296    pub async fn set_acceleration_callback_configuration(
1297        &mut self,
1298        period: u32,
1299        value_has_to_change: bool,
1300    ) -> Result<(), TinkerforgeError> {
1301        let mut payload = [0; 5];
1302        period.write_to_slice(&mut payload[0..4]);
1303        value_has_to_change.write_to_slice(&mut payload[4..5]);
1304
1305        #[allow(unused_variables)]
1306        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetAccelerationCallbackConfiguration), &payload).await?;
1307        Ok(())
1308    }
1309
1310    /// Returns the receiver configuration as set by [`set_acceleration_callback_configuration`].
1311    pub async fn get_acceleration_callback_configuration(&mut self) -> Result<AccelerationCallbackConfiguration, TinkerforgeError> {
1312        let payload = [0; 0];
1313
1314        #[allow(unused_variables)]
1315        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetAccelerationCallbackConfiguration), &payload).await?;
1316        Ok(AccelerationCallbackConfiguration::from_le_byte_slice(result.body()))
1317    }
1318
1319    /// The period is the period with which the [`get_magnetic_field_callback_receiver`] receiver
1320    /// is triggered periodically. A value of 0 turns the receiver off.
1321    ///
1322    /// If the `value has to change`-parameter is set to true, the receiver is only
1323    /// triggered after the value has changed. If the value didn't change within the
1324    /// period, the receiver is triggered immediately on change.
1325    ///
1326    /// If it is set to false, the receiver is continuously triggered with the period,
1327    /// independent of the value.
1328    pub async fn set_magnetic_field_callback_configuration(
1329        &mut self,
1330        period: u32,
1331        value_has_to_change: bool,
1332    ) -> Result<(), TinkerforgeError> {
1333        let mut payload = [0; 5];
1334        period.write_to_slice(&mut payload[0..4]);
1335        value_has_to_change.write_to_slice(&mut payload[4..5]);
1336
1337        #[allow(unused_variables)]
1338        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetMagneticFieldCallbackConfiguration), &payload).await?;
1339        Ok(())
1340    }
1341
1342    /// Returns the receiver configuration as set by [`set_magnetic_field_callback_configuration`].
1343    pub async fn get_magnetic_field_callback_configuration(&mut self) -> Result<MagneticFieldCallbackConfiguration, TinkerforgeError> {
1344        let payload = [0; 0];
1345
1346        #[allow(unused_variables)]
1347        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetMagneticFieldCallbackConfiguration), &payload).await?;
1348        Ok(MagneticFieldCallbackConfiguration::from_le_byte_slice(result.body()))
1349    }
1350
1351    /// The period is the period with which the [`get_angular_velocity_callback_receiver`] receiver
1352    /// is triggered periodically. A value of 0 turns the receiver off.
1353    ///
1354    /// If the `value has to change`-parameter is set to true, the receiver is only
1355    /// triggered after the value has changed. If the value didn't change within the
1356    /// period, the receiver is triggered immediately on change.
1357    ///
1358    /// If it is set to false, the receiver is continuously triggered with the period,
1359    /// independent of the value.
1360    pub async fn set_angular_velocity_callback_configuration(
1361        &mut self,
1362        period: u32,
1363        value_has_to_change: bool,
1364    ) -> Result<(), TinkerforgeError> {
1365        let mut payload = [0; 5];
1366        period.write_to_slice(&mut payload[0..4]);
1367        value_has_to_change.write_to_slice(&mut payload[4..5]);
1368
1369        #[allow(unused_variables)]
1370        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetAngularVelocityCallbackConfiguration), &payload).await?;
1371        Ok(())
1372    }
1373
1374    /// Returns the receiver configuration as set by [`set_angular_velocity_callback_configuration`].
1375    pub async fn get_angular_velocity_callback_configuration(&mut self) -> Result<AngularVelocityCallbackConfiguration, TinkerforgeError> {
1376        let payload = [0; 0];
1377
1378        #[allow(unused_variables)]
1379        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetAngularVelocityCallbackConfiguration), &payload).await?;
1380        Ok(AngularVelocityCallbackConfiguration::from_le_byte_slice(result.body()))
1381    }
1382
1383    /// The period is the period with which the [`get_temperature_callback_receiver`] receiver
1384    /// is triggered periodically. A value of 0 turns the receiver off.
1385    ///
1386    /// If the `value has to change`-parameter is set to true, the receiver is only
1387    /// triggered after the value has changed. If the value didn't change within the
1388    /// period, the receiver is triggered immediately on change.
1389    ///
1390    /// If it is set to false, the receiver is continuously triggered with the period,
1391    /// independent of the value.
1392    pub async fn set_temperature_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
1393        let mut payload = [0; 5];
1394        period.write_to_slice(&mut payload[0..4]);
1395        value_has_to_change.write_to_slice(&mut payload[4..5]);
1396
1397        #[allow(unused_variables)]
1398        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetTemperatureCallbackConfiguration), &payload).await?;
1399        Ok(())
1400    }
1401
1402    /// Returns the receiver configuration as set by [`set_temperature_callback_configuration`].
1403    pub async fn get_temperature_callback_configuration(&mut self) -> Result<TemperatureCallbackConfiguration, TinkerforgeError> {
1404        let payload = [0; 0];
1405
1406        #[allow(unused_variables)]
1407        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetTemperatureCallbackConfiguration), &payload).await?;
1408        Ok(TemperatureCallbackConfiguration::from_le_byte_slice(result.body()))
1409    }
1410
1411    /// The period is the period with which the [`get_orientation_callback_receiver`] receiver
1412    /// is triggered periodically. A value of 0 turns the receiver off.
1413    ///
1414    /// If the `value has to change`-parameter is set to true, the receiver is only
1415    /// triggered after the value has changed. If the value didn't change within the
1416    /// period, the receiver is triggered immediately on change.
1417    ///
1418    /// If it is set to false, the receiver is continuously triggered with the period,
1419    /// independent of the value.
1420    pub async fn set_orientation_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
1421        let mut payload = [0; 5];
1422        period.write_to_slice(&mut payload[0..4]);
1423        value_has_to_change.write_to_slice(&mut payload[4..5]);
1424
1425        #[allow(unused_variables)]
1426        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetOrientationCallbackConfiguration), &payload).await?;
1427        Ok(())
1428    }
1429
1430    /// Returns the receiver configuration as set by [`set_orientation_callback_configuration`].
1431    pub async fn get_orientation_callback_configuration(&mut self) -> Result<OrientationCallbackConfiguration, TinkerforgeError> {
1432        let payload = [0; 0];
1433
1434        #[allow(unused_variables)]
1435        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetOrientationCallbackConfiguration), &payload).await?;
1436        Ok(OrientationCallbackConfiguration::from_le_byte_slice(result.body()))
1437    }
1438
1439    /// The period is the period with which the [`get_linear_acceleration_callback_receiver`] receiver
1440    /// is triggered periodically. A value of 0 turns the receiver off.
1441    ///
1442    /// If the `value has to change`-parameter is set to true, the receiver is only
1443    /// triggered after the value has changed. If the value didn't change within the
1444    /// period, the receiver is triggered immediately on change.
1445    ///
1446    /// If it is set to false, the receiver is continuously triggered with the period,
1447    /// independent of the value.
1448    pub async fn set_linear_acceleration_callback_configuration(
1449        &mut self,
1450        period: u32,
1451        value_has_to_change: bool,
1452    ) -> Result<(), TinkerforgeError> {
1453        let mut payload = [0; 5];
1454        period.write_to_slice(&mut payload[0..4]);
1455        value_has_to_change.write_to_slice(&mut payload[4..5]);
1456
1457        #[allow(unused_variables)]
1458        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetLinearAccelerationCallbackConfiguration), &payload).await?;
1459        Ok(())
1460    }
1461
1462    /// Returns the receiver configuration as set by [`set_linear_acceleration_callback_configuration`].
1463    pub async fn get_linear_acceleration_callback_configuration(
1464        &mut self,
1465    ) -> Result<LinearAccelerationCallbackConfiguration, TinkerforgeError> {
1466        let payload = [0; 0];
1467
1468        #[allow(unused_variables)]
1469        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetLinearAccelerationCallbackConfiguration), &payload).await?;
1470        Ok(LinearAccelerationCallbackConfiguration::from_le_byte_slice(result.body()))
1471    }
1472
1473    /// The period is the period with which the [`get_gravity_vector_callback_receiver`] receiver
1474    /// is triggered periodically. A value of 0 turns the receiver off.
1475    ///
1476    /// If the `value has to change`-parameter is set to true, the receiver is only
1477    /// triggered after the value has changed. If the value didn't change within the
1478    /// period, the receiver is triggered immediately on change.
1479    ///
1480    /// If it is set to false, the receiver is continuously triggered with the period,
1481    /// independent of the value.
1482    pub async fn set_gravity_vector_callback_configuration(
1483        &mut self,
1484        period: u32,
1485        value_has_to_change: bool,
1486    ) -> Result<(), TinkerforgeError> {
1487        let mut payload = [0; 5];
1488        period.write_to_slice(&mut payload[0..4]);
1489        value_has_to_change.write_to_slice(&mut payload[4..5]);
1490
1491        #[allow(unused_variables)]
1492        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetGravityVectorCallbackConfiguration), &payload).await?;
1493        Ok(())
1494    }
1495
1496    /// Returns the receiver configuration as set by [`set_gravity_vector_callback_configuration`].
1497    pub async fn get_gravity_vector_callback_configuration(&mut self) -> Result<GravityVectorCallbackConfiguration, TinkerforgeError> {
1498        let payload = [0; 0];
1499
1500        #[allow(unused_variables)]
1501        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetGravityVectorCallbackConfiguration), &payload).await?;
1502        Ok(GravityVectorCallbackConfiguration::from_le_byte_slice(result.body()))
1503    }
1504
1505    /// The period is the period with which the [`get_quaternion_callback_receiver`] receiver
1506    /// is triggered periodically. A value of 0 turns the receiver off.
1507    ///
1508    /// If the `value has to change`-parameter is set to true, the receiver is only
1509    /// triggered after the value has changed. If the value didn't change within the
1510    /// period, the receiver is triggered immediately on change.
1511    ///
1512    /// If it is set to false, the receiver is continuously triggered with the period,
1513    /// independent of the value.
1514    pub async fn set_quaternion_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
1515        let mut payload = [0; 5];
1516        period.write_to_slice(&mut payload[0..4]);
1517        value_has_to_change.write_to_slice(&mut payload[4..5]);
1518
1519        #[allow(unused_variables)]
1520        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetQuaternionCallbackConfiguration), &payload).await?;
1521        Ok(())
1522    }
1523
1524    /// Returns the receiver configuration as set by [`set_quaternion_callback_configuration`].
1525    pub async fn get_quaternion_callback_configuration(&mut self) -> Result<QuaternionCallbackConfiguration, TinkerforgeError> {
1526        let payload = [0; 0];
1527
1528        #[allow(unused_variables)]
1529        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetQuaternionCallbackConfiguration), &payload).await?;
1530        Ok(QuaternionCallbackConfiguration::from_le_byte_slice(result.body()))
1531    }
1532
1533    /// The period is the period with which the [`get_all_data_callback_receiver`] receiver
1534    /// is triggered periodically. A value of 0 turns the receiver off.
1535    ///
1536    /// If the `value has to change`-parameter is set to true, the receiver is only
1537    /// triggered after the value has changed. If the value didn't change within the
1538    /// period, the receiver is triggered immediately on change.
1539    ///
1540    /// If it is set to false, the receiver is continuously triggered with the period,
1541    /// independent of the value.
1542    pub async fn set_all_data_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
1543        let mut payload = [0; 5];
1544        period.write_to_slice(&mut payload[0..4]);
1545        value_has_to_change.write_to_slice(&mut payload[4..5]);
1546
1547        #[allow(unused_variables)]
1548        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetAllDataCallbackConfiguration), &payload).await?;
1549        Ok(())
1550    }
1551
1552    /// Returns the receiver configuration as set by [`set_all_data_callback_configuration`].
1553    pub async fn get_all_data_callback_configuration(&mut self) -> Result<AllDataCallbackConfiguration, TinkerforgeError> {
1554        let payload = [0; 0];
1555
1556        #[allow(unused_variables)]
1557        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetAllDataCallbackConfiguration), &payload).await?;
1558        Ok(AllDataCallbackConfiguration::from_le_byte_slice(result.body()))
1559    }
1560
1561    /// Returns the error count for the communication between Brick and Bricklet.
1562    ///
1563    /// The errors are divided into
1564    ///
1565    /// * ACK checksum errors,
1566    /// * message checksum errors,
1567    /// * framing errors and
1568    /// * overflow errors.
1569    ///
1570    /// The errors counts are for errors that occur on the Bricklet side. All
1571    /// Bricks have a similar function that returns the errors on the Brick side.
1572    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
1573        let payload = [0; 0];
1574
1575        #[allow(unused_variables)]
1576        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetSpitfpErrorCount), &payload).await?;
1577        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
1578    }
1579
1580    /// Sets the bootloader mode and returns the status after the requested
1581    /// mode change was instigated.
1582    ///
1583    /// You can change from bootloader mode to firmware mode and vice versa. A change
1584    /// from bootloader mode to firmware mode will only take place if the entry function,
1585    /// device identifier and CRC are present and correct.
1586    ///
1587    /// This function is used by Brick Viewer during flashing. It should not be
1588    /// necessary to call it in a normal user program.
1589    ///
1590    /// Associated constants:
1591    /// * IMU_V3_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1592    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1593    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1594    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1595    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1596    ///	* IMU_V3_BRICKLET_BOOTLOADER_STATUS_OK
1597    ///	* IMU_V3_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
1598    ///	* IMU_V3_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
1599    ///	* IMU_V3_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
1600    ///	* IMU_V3_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
1601    ///	* IMU_V3_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
1602    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
1603        let mut payload = [0; 1];
1604        mode.write_to_slice(&mut payload[0..1]);
1605
1606        #[allow(unused_variables)]
1607        let result = self.device.get(u8::from(ImuV3BrickletFunction::SetBootloaderMode), &payload).await?;
1608        Ok(u8::from_le_byte_slice(result.body()))
1609    }
1610
1611    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
1612    ///
1613    /// Associated constants:
1614    /// * IMU_V3_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1615    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1616    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1617    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1618    ///	* IMU_V3_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1619    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
1620        let payload = [0; 0];
1621
1622        #[allow(unused_variables)]
1623        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetBootloaderMode), &payload).await?;
1624        Ok(u8::from_le_byte_slice(result.body()))
1625    }
1626
1627    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
1628    /// to be increased by chunks of size 64. The data is written to flash
1629    /// every 4 chunks (which equals to one page of size 256).
1630    ///
1631    /// This function is used by Brick Viewer during flashing. It should not be
1632    /// necessary to call it in a normal user program.
1633    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
1634        let mut payload = [0; 4];
1635        pointer.write_to_slice(&mut payload[0..4]);
1636
1637        #[allow(unused_variables)]
1638        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetWriteFirmwarePointer), &payload).await?;
1639        Ok(())
1640    }
1641
1642    /// Writes 64 Bytes of firmware at the position as written by
1643    /// [`set_write_firmware_pointer`] before. The firmware is written
1644    /// to flash every 4 chunks.
1645    ///
1646    /// You can only write firmware in bootloader mode.
1647    ///
1648    /// This function is used by Brick Viewer during flashing. It should not be
1649    /// necessary to call it in a normal user program.
1650    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
1651        let mut payload = [0; 64];
1652        data.write_to_slice(&mut payload[0..64]);
1653
1654        #[allow(unused_variables)]
1655        let result = self.device.get(u8::from(ImuV3BrickletFunction::WriteFirmware), &payload).await?;
1656        Ok(u8::from_le_byte_slice(result.body()))
1657    }
1658
1659    /// Sets the status LED configuration. By default the LED shows
1660    /// communication traffic between Brick and Bricklet, it flickers once
1661    /// for every 10 received data packets.
1662    ///
1663    /// You can also turn the LED permanently on/off or show a heartbeat.
1664    ///
1665    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
1666    ///
1667    /// Associated constants:
1668    /// * IMU_V3_BRICKLET_STATUS_LED_CONFIG_OFF
1669    ///	* IMU_V3_BRICKLET_STATUS_LED_CONFIG_ON
1670    ///	* IMU_V3_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1671    ///	* IMU_V3_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1672    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
1673        let mut payload = [0; 1];
1674        config.write_to_slice(&mut payload[0..1]);
1675
1676        #[allow(unused_variables)]
1677        let result = self.device.set(u8::from(ImuV3BrickletFunction::SetStatusLedConfig), &payload).await?;
1678        Ok(())
1679    }
1680
1681    /// Returns the configuration as set by [`set_status_led_config`]
1682    ///
1683    /// Associated constants:
1684    /// * IMU_V3_BRICKLET_STATUS_LED_CONFIG_OFF
1685    ///	* IMU_V3_BRICKLET_STATUS_LED_CONFIG_ON
1686    ///	* IMU_V3_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1687    ///	* IMU_V3_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1688    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
1689        let payload = [0; 0];
1690
1691        #[allow(unused_variables)]
1692        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetStatusLedConfig), &payload).await?;
1693        Ok(u8::from_le_byte_slice(result.body()))
1694    }
1695
1696    /// Returns the temperature as measured inside the microcontroller. The
1697    /// value returned is not the ambient temperature!
1698    ///
1699    /// The temperature is only proportional to the real temperature and it has bad
1700    /// accuracy. Practically it is only useful as an indicator for
1701    /// temperature changes.
1702    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
1703        let payload = [0; 0];
1704
1705        #[allow(unused_variables)]
1706        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetChipTemperature), &payload).await?;
1707        Ok(i16::from_le_byte_slice(result.body()))
1708    }
1709
1710    /// Calling this function will reset the Bricklet. All configurations
1711    /// will be lost.
1712    ///
1713    /// After a reset you have to create new device objects,
1714    /// calling functions on the existing ones will result in
1715    /// undefined behavior!
1716    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
1717        let payload = [0; 0];
1718
1719        #[allow(unused_variables)]
1720        let result = self.device.set(u8::from(ImuV3BrickletFunction::Reset), &payload).await?;
1721        Ok(())
1722    }
1723
1724    /// Writes a new UID into flash. If you want to set a new UID
1725    /// you have to decode the Base58 encoded UID string into an
1726    /// integer first.
1727    ///
1728    /// We recommend that you use Brick Viewer to change the UID.
1729    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
1730        let mut payload = [0; 4];
1731        uid.write_to_slice(&mut payload[0..4]);
1732
1733        #[allow(unused_variables)]
1734        let result = self.device.set(u8::from(ImuV3BrickletFunction::WriteUid), &payload).await?;
1735        Ok(())
1736    }
1737
1738    /// Returns the current UID as an integer. Encode as
1739    /// Base58 to get the usual string version.
1740    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
1741        let payload = [0; 0];
1742
1743        #[allow(unused_variables)]
1744        let result = self.device.get(u8::from(ImuV3BrickletFunction::ReadUid), &payload).await?;
1745        Ok(u32::from_le_byte_slice(result.body()))
1746    }
1747
1748    /// Returns the UID, the UID where the Bricklet is connected to,
1749    /// the position, the hardware and firmware version as well as the
1750    /// device identifier.
1751    ///
1752    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
1753    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
1754    /// position 'z'.
1755    ///
1756    /// The device identifier numbers can be found [here](device_identifier).
1757    /// |device_identifier_constant|
1758    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
1759        let payload = [0; 0];
1760
1761        #[allow(unused_variables)]
1762        let result = self.device.get(u8::from(ImuV3BrickletFunction::GetIdentity), &payload).await?;
1763        Ok(Identity::from_le_byte_slice(result.body()))
1764    }
1765}