tinkerforge_async/bindings/
silent_stepper_v2_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//! Silently drives one bipolar stepper motor with up to 46V and 1.6A per phase.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/SilentStepperV2_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 SilentStepperV2BrickletFunction {
24    SetMaxVelocity,
25    GetMaxVelocity,
26    GetCurrentVelocity,
27    SetSpeedRamping,
28    GetSpeedRamping,
29    FullBrake,
30    SetCurrentPosition,
31    GetCurrentPosition,
32    SetTargetPosition,
33    GetTargetPosition,
34    SetSteps,
35    GetSteps,
36    GetRemainingSteps,
37    SetStepConfiguration,
38    GetStepConfiguration,
39    DriveForward,
40    DriveBackward,
41    Stop,
42    GetInputVoltage,
43    SetMotorCurrent,
44    GetMotorCurrent,
45    SetEnabled,
46    GetEnabled,
47    SetBasicConfiguration,
48    GetBasicConfiguration,
49    SetSpreadcycleConfiguration,
50    GetSpreadcycleConfiguration,
51    SetStealthConfiguration,
52    GetStealthConfiguration,
53    SetCoolstepConfiguration,
54    GetCoolstepConfiguration,
55    SetMiscConfiguration,
56    GetMiscConfiguration,
57    SetErrorLedConfig,
58    GetErrorLedConfig,
59    GetDriverStatus,
60    SetMinimumVoltage,
61    GetMinimumVoltage,
62    SetTimeBase,
63    GetTimeBase,
64    GetAllData,
65    SetAllCallbackConfiguration,
66    GetAllDataCallbackConfiguraton,
67    SetGpioConfiguration,
68    GetGpioConfiguration,
69    SetGpioAction,
70    GetGpioAction,
71    GetGpioState,
72    GetSpitfpErrorCount,
73    SetBootloaderMode,
74    GetBootloaderMode,
75    SetWriteFirmwarePointer,
76    WriteFirmware,
77    SetStatusLedConfig,
78    GetStatusLedConfig,
79    GetChipTemperature,
80    Reset,
81    WriteUid,
82    ReadUid,
83    GetIdentity,
84    CallbackUnderVoltage,
85    CallbackPositionReached,
86    CallbackAllData,
87    CallbackNewState,
88    CallbackGpioState,
89}
90impl From<SilentStepperV2BrickletFunction> for u8 {
91    fn from(fun: SilentStepperV2BrickletFunction) -> Self {
92        match fun {
93            SilentStepperV2BrickletFunction::SetMaxVelocity => 1,
94            SilentStepperV2BrickletFunction::GetMaxVelocity => 2,
95            SilentStepperV2BrickletFunction::GetCurrentVelocity => 3,
96            SilentStepperV2BrickletFunction::SetSpeedRamping => 4,
97            SilentStepperV2BrickletFunction::GetSpeedRamping => 5,
98            SilentStepperV2BrickletFunction::FullBrake => 6,
99            SilentStepperV2BrickletFunction::SetCurrentPosition => 7,
100            SilentStepperV2BrickletFunction::GetCurrentPosition => 8,
101            SilentStepperV2BrickletFunction::SetTargetPosition => 9,
102            SilentStepperV2BrickletFunction::GetTargetPosition => 10,
103            SilentStepperV2BrickletFunction::SetSteps => 11,
104            SilentStepperV2BrickletFunction::GetSteps => 12,
105            SilentStepperV2BrickletFunction::GetRemainingSteps => 13,
106            SilentStepperV2BrickletFunction::SetStepConfiguration => 14,
107            SilentStepperV2BrickletFunction::GetStepConfiguration => 15,
108            SilentStepperV2BrickletFunction::DriveForward => 16,
109            SilentStepperV2BrickletFunction::DriveBackward => 17,
110            SilentStepperV2BrickletFunction::Stop => 18,
111            SilentStepperV2BrickletFunction::GetInputVoltage => 19,
112            SilentStepperV2BrickletFunction::SetMotorCurrent => 22,
113            SilentStepperV2BrickletFunction::GetMotorCurrent => 23,
114            SilentStepperV2BrickletFunction::SetEnabled => 24,
115            SilentStepperV2BrickletFunction::GetEnabled => 25,
116            SilentStepperV2BrickletFunction::SetBasicConfiguration => 26,
117            SilentStepperV2BrickletFunction::GetBasicConfiguration => 27,
118            SilentStepperV2BrickletFunction::SetSpreadcycleConfiguration => 28,
119            SilentStepperV2BrickletFunction::GetSpreadcycleConfiguration => 29,
120            SilentStepperV2BrickletFunction::SetStealthConfiguration => 30,
121            SilentStepperV2BrickletFunction::GetStealthConfiguration => 31,
122            SilentStepperV2BrickletFunction::SetCoolstepConfiguration => 32,
123            SilentStepperV2BrickletFunction::GetCoolstepConfiguration => 33,
124            SilentStepperV2BrickletFunction::SetMiscConfiguration => 34,
125            SilentStepperV2BrickletFunction::GetMiscConfiguration => 35,
126            SilentStepperV2BrickletFunction::SetErrorLedConfig => 36,
127            SilentStepperV2BrickletFunction::GetErrorLedConfig => 37,
128            SilentStepperV2BrickletFunction::GetDriverStatus => 38,
129            SilentStepperV2BrickletFunction::SetMinimumVoltage => 39,
130            SilentStepperV2BrickletFunction::GetMinimumVoltage => 40,
131            SilentStepperV2BrickletFunction::SetTimeBase => 43,
132            SilentStepperV2BrickletFunction::GetTimeBase => 44,
133            SilentStepperV2BrickletFunction::GetAllData => 45,
134            SilentStepperV2BrickletFunction::SetAllCallbackConfiguration => 46,
135            SilentStepperV2BrickletFunction::GetAllDataCallbackConfiguraton => 47,
136            SilentStepperV2BrickletFunction::SetGpioConfiguration => 48,
137            SilentStepperV2BrickletFunction::GetGpioConfiguration => 49,
138            SilentStepperV2BrickletFunction::SetGpioAction => 50,
139            SilentStepperV2BrickletFunction::GetGpioAction => 51,
140            SilentStepperV2BrickletFunction::GetGpioState => 52,
141            SilentStepperV2BrickletFunction::GetSpitfpErrorCount => 234,
142            SilentStepperV2BrickletFunction::SetBootloaderMode => 235,
143            SilentStepperV2BrickletFunction::GetBootloaderMode => 236,
144            SilentStepperV2BrickletFunction::SetWriteFirmwarePointer => 237,
145            SilentStepperV2BrickletFunction::WriteFirmware => 238,
146            SilentStepperV2BrickletFunction::SetStatusLedConfig => 239,
147            SilentStepperV2BrickletFunction::GetStatusLedConfig => 240,
148            SilentStepperV2BrickletFunction::GetChipTemperature => 242,
149            SilentStepperV2BrickletFunction::Reset => 243,
150            SilentStepperV2BrickletFunction::WriteUid => 248,
151            SilentStepperV2BrickletFunction::ReadUid => 249,
152            SilentStepperV2BrickletFunction::GetIdentity => 255,
153            SilentStepperV2BrickletFunction::CallbackUnderVoltage => 41,
154            SilentStepperV2BrickletFunction::CallbackPositionReached => 42,
155            SilentStepperV2BrickletFunction::CallbackAllData => 53,
156            SilentStepperV2BrickletFunction::CallbackNewState => 54,
157            SilentStepperV2BrickletFunction::CallbackGpioState => 55,
158        }
159    }
160}
161pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_1: u8 = 8;
162pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_2: u8 = 7;
163pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_4: u8 = 6;
164pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_8: u8 = 5;
165pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_16: u8 = 4;
166pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_32: u8 = 3;
167pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_64: u8 = 2;
168pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_128: u8 = 1;
169pub const SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_256: u8 = 0;
170pub const SILENT_STEPPER_V2_BRICKLET_CHOPPER_MODE_SPREAD_CYCLE: u8 = 0;
171pub const SILENT_STEPPER_V2_BRICKLET_CHOPPER_MODE_FAST_DECAY: u8 = 1;
172pub const SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_NORMAL: u8 = 0;
173pub const SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_FREEWHEELING: u8 = 1;
174pub const SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_COIL_SHORT_LS: u8 = 2;
175pub const SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_COIL_SHORT_HS: u8 = 3;
176pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_1: u8 = 0;
177pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_2: u8 = 1;
178pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_4: u8 = 2;
179pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_8: u8 = 3;
180pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_1: u8 = 0;
181pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_2: u8 = 1;
182pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_8: u8 = 2;
183pub const SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_32: u8 = 3;
184pub const SILENT_STEPPER_V2_BRICKLET_MINIMUM_CURRENT_HALF: u8 = 0;
185pub const SILENT_STEPPER_V2_BRICKLET_MINIMUM_CURRENT_QUARTER: u8 = 1;
186pub const SILENT_STEPPER_V2_BRICKLET_STALLGUARD_MODE_STANDARD: u8 = 0;
187pub const SILENT_STEPPER_V2_BRICKLET_STALLGUARD_MODE_FILTERED: u8 = 1;
188pub const SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_NONE: u8 = 0;
189pub const SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_PHASE_A: u8 = 1;
190pub const SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_PHASE_B: u8 = 2;
191pub const SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_PHASE_AB: u8 = 3;
192pub const SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_NONE: u8 = 0;
193pub const SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_PHASE_A: u8 = 1;
194pub const SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_PHASE_B: u8 = 2;
195pub const SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_PHASE_AB: u8 = 3;
196pub const SILENT_STEPPER_V2_BRICKLET_OVER_TEMPERATURE_NONE: u8 = 0;
197pub const SILENT_STEPPER_V2_BRICKLET_OVER_TEMPERATURE_WARNING: u8 = 1;
198pub const SILENT_STEPPER_V2_BRICKLET_OVER_TEMPERATURE_LIMIT: u8 = 2;
199pub const SILENT_STEPPER_V2_BRICKLET_STATE_STOP: u8 = 1;
200pub const SILENT_STEPPER_V2_BRICKLET_STATE_ACCELERATION: u8 = 2;
201pub const SILENT_STEPPER_V2_BRICKLET_STATE_RUN: u8 = 3;
202pub const SILENT_STEPPER_V2_BRICKLET_STATE_DEACCELERATION: u8 = 4;
203pub const SILENT_STEPPER_V2_BRICKLET_STATE_DIRECTION_CHANGE_TO_FORWARD: u8 = 5;
204pub const SILENT_STEPPER_V2_BRICKLET_STATE_DIRECTION_CHANGE_TO_BACKWARD: u8 = 6;
205pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NONE: u32 = 0;
206pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NORMAL_STOP_RISING_EDGE: u32 = 1;
207pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NORMAL_STOP_FALLING_EDGE: u32 = 2;
208pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_FULL_BRAKE_RISING_EDGE: u32 = 4;
209pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_FULL_BRAKE_FALLING_EDGE: u32 = 8;
210pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_CALLBACK_RISING_EDGE: u32 = 16;
211pub const SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_CALLBACK_FALLING_EDGE: u32 = 32;
212pub const SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_OFF: u8 = 0;
213pub const SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_ON: u8 = 1;
214pub const SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
215pub const SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR: u8 = 3;
216pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
217pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
218pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
219pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
220pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
221pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
222pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
223pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
224pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
225pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
226pub const SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
227pub const SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
228pub const SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
229pub const SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
230pub const SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
231
232#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
233pub struct SpeedRamping {
234    pub acceleration: u16,
235    pub deacceleration: u16,
236}
237impl FromByteSlice for SpeedRamping {
238    fn bytes_expected() -> usize {
239        4
240    }
241    fn from_le_byte_slice(bytes: &[u8]) -> SpeedRamping {
242        SpeedRamping { acceleration: <u16>::from_le_byte_slice(&bytes[0..2]), deacceleration: <u16>::from_le_byte_slice(&bytes[2..4]) }
243    }
244}
245
246#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
247pub struct StepConfiguration {
248    pub step_resolution: u8,
249    pub interpolation: bool,
250}
251impl FromByteSlice for StepConfiguration {
252    fn bytes_expected() -> usize {
253        2
254    }
255    fn from_le_byte_slice(bytes: &[u8]) -> StepConfiguration {
256        StepConfiguration {
257            step_resolution: <u8>::from_le_byte_slice(&bytes[0..1]),
258            interpolation: <bool>::from_le_byte_slice(&bytes[1..2]),
259        }
260    }
261}
262
263#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
264pub struct BasicConfiguration {
265    pub standstill_current: u16,
266    pub motor_run_current: u16,
267    pub standstill_delay_time: u16,
268    pub power_down_time: u16,
269    pub stealth_threshold: u16,
270    pub coolstep_threshold: u16,
271    pub classic_threshold: u16,
272    pub high_velocity_chopper_mode: bool,
273}
274impl FromByteSlice for BasicConfiguration {
275    fn bytes_expected() -> usize {
276        15
277    }
278    fn from_le_byte_slice(bytes: &[u8]) -> BasicConfiguration {
279        BasicConfiguration {
280            standstill_current: <u16>::from_le_byte_slice(&bytes[0..2]),
281            motor_run_current: <u16>::from_le_byte_slice(&bytes[2..4]),
282            standstill_delay_time: <u16>::from_le_byte_slice(&bytes[4..6]),
283            power_down_time: <u16>::from_le_byte_slice(&bytes[6..8]),
284            stealth_threshold: <u16>::from_le_byte_slice(&bytes[8..10]),
285            coolstep_threshold: <u16>::from_le_byte_slice(&bytes[10..12]),
286            classic_threshold: <u16>::from_le_byte_slice(&bytes[12..14]),
287            high_velocity_chopper_mode: <bool>::from_le_byte_slice(&bytes[14..15]),
288        }
289    }
290}
291
292#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
293pub struct SpreadcycleConfiguration {
294    pub slow_decay_duration: u8,
295    pub enable_random_slow_decay: bool,
296    pub fast_decay_duration: u8,
297    pub hysteresis_start_value: u8,
298    pub hysteresis_end_value: i8,
299    pub sine_wave_offset: i8,
300    pub chopper_mode: u8,
301    pub comparator_blank_time: u8,
302    pub fast_decay_without_comparator: bool,
303}
304impl FromByteSlice for SpreadcycleConfiguration {
305    fn bytes_expected() -> usize {
306        9
307    }
308    fn from_le_byte_slice(bytes: &[u8]) -> SpreadcycleConfiguration {
309        SpreadcycleConfiguration {
310            slow_decay_duration: <u8>::from_le_byte_slice(&bytes[0..1]),
311            enable_random_slow_decay: <bool>::from_le_byte_slice(&bytes[1..2]),
312            fast_decay_duration: <u8>::from_le_byte_slice(&bytes[2..3]),
313            hysteresis_start_value: <u8>::from_le_byte_slice(&bytes[3..4]),
314            hysteresis_end_value: <i8>::from_le_byte_slice(&bytes[4..5]),
315            sine_wave_offset: <i8>::from_le_byte_slice(&bytes[5..6]),
316            chopper_mode: <u8>::from_le_byte_slice(&bytes[6..7]),
317            comparator_blank_time: <u8>::from_le_byte_slice(&bytes[7..8]),
318            fast_decay_without_comparator: <bool>::from_le_byte_slice(&bytes[8..9]),
319        }
320    }
321}
322
323#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
324pub struct StealthConfiguration {
325    pub enable_stealth: bool,
326    pub amplitude: u8,
327    pub gradient: u8,
328    pub enable_autoscale: bool,
329    pub force_symmetric: bool,
330    pub freewheel_mode: u8,
331}
332impl FromByteSlice for StealthConfiguration {
333    fn bytes_expected() -> usize {
334        6
335    }
336    fn from_le_byte_slice(bytes: &[u8]) -> StealthConfiguration {
337        StealthConfiguration {
338            enable_stealth: <bool>::from_le_byte_slice(&bytes[0..1]),
339            amplitude: <u8>::from_le_byte_slice(&bytes[1..2]),
340            gradient: <u8>::from_le_byte_slice(&bytes[2..3]),
341            enable_autoscale: <bool>::from_le_byte_slice(&bytes[3..4]),
342            force_symmetric: <bool>::from_le_byte_slice(&bytes[4..5]),
343            freewheel_mode: <u8>::from_le_byte_slice(&bytes[5..6]),
344        }
345    }
346}
347
348#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
349pub struct CoolstepConfiguration {
350    pub minimum_stallguard_value: u8,
351    pub maximum_stallguard_value: u8,
352    pub current_up_step_width: u8,
353    pub current_down_step_width: u8,
354    pub minimum_current: u8,
355    pub stallguard_threshold_value: i8,
356    pub stallguard_mode: u8,
357}
358impl FromByteSlice for CoolstepConfiguration {
359    fn bytes_expected() -> usize {
360        7
361    }
362    fn from_le_byte_slice(bytes: &[u8]) -> CoolstepConfiguration {
363        CoolstepConfiguration {
364            minimum_stallguard_value: <u8>::from_le_byte_slice(&bytes[0..1]),
365            maximum_stallguard_value: <u8>::from_le_byte_slice(&bytes[1..2]),
366            current_up_step_width: <u8>::from_le_byte_slice(&bytes[2..3]),
367            current_down_step_width: <u8>::from_le_byte_slice(&bytes[3..4]),
368            minimum_current: <u8>::from_le_byte_slice(&bytes[4..5]),
369            stallguard_threshold_value: <i8>::from_le_byte_slice(&bytes[5..6]),
370            stallguard_mode: <u8>::from_le_byte_slice(&bytes[6..7]),
371        }
372    }
373}
374
375#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
376pub struct MiscConfiguration {
377    pub disable_short_to_ground_protection: bool,
378    pub synchronize_phase_frequency: u8,
379}
380impl FromByteSlice for MiscConfiguration {
381    fn bytes_expected() -> usize {
382        2
383    }
384    fn from_le_byte_slice(bytes: &[u8]) -> MiscConfiguration {
385        MiscConfiguration {
386            disable_short_to_ground_protection: <bool>::from_le_byte_slice(&bytes[0..1]),
387            synchronize_phase_frequency: <u8>::from_le_byte_slice(&bytes[1..2]),
388        }
389    }
390}
391
392#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
393pub struct DriverStatus {
394    pub open_load: u8,
395    pub short_to_ground: u8,
396    pub over_temperature: u8,
397    pub motor_stalled: bool,
398    pub actual_motor_current: u8,
399    pub full_step_active: bool,
400    pub stallguard_result: u8,
401    pub stealth_voltage_amplitude: u8,
402}
403impl FromByteSlice for DriverStatus {
404    fn bytes_expected() -> usize {
405        8
406    }
407    fn from_le_byte_slice(bytes: &[u8]) -> DriverStatus {
408        DriverStatus {
409            open_load: <u8>::from_le_byte_slice(&bytes[0..1]),
410            short_to_ground: <u8>::from_le_byte_slice(&bytes[1..2]),
411            over_temperature: <u8>::from_le_byte_slice(&bytes[2..3]),
412            motor_stalled: <bool>::from_le_byte_slice(&bytes[3..4]),
413            actual_motor_current: <u8>::from_le_byte_slice(&bytes[4..5]),
414            full_step_active: <bool>::from_le_byte_slice(&bytes[5..6]),
415            stallguard_result: <u8>::from_le_byte_slice(&bytes[6..7]),
416            stealth_voltage_amplitude: <u8>::from_le_byte_slice(&bytes[7..8]),
417        }
418    }
419}
420
421#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
422pub struct AllData {
423    pub current_velocity: u16,
424    pub current_position: i32,
425    pub remaining_steps: i32,
426    pub input_voltage: u16,
427    pub current_consumption: u16,
428}
429impl FromByteSlice for AllData {
430    fn bytes_expected() -> usize {
431        14
432    }
433    fn from_le_byte_slice(bytes: &[u8]) -> AllData {
434        AllData {
435            current_velocity: <u16>::from_le_byte_slice(&bytes[0..2]),
436            current_position: <i32>::from_le_byte_slice(&bytes[2..6]),
437            remaining_steps: <i32>::from_le_byte_slice(&bytes[6..10]),
438            input_voltage: <u16>::from_le_byte_slice(&bytes[10..12]),
439            current_consumption: <u16>::from_le_byte_slice(&bytes[12..14]),
440        }
441    }
442}
443
444#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
445pub struct GpioConfiguration {
446    pub debounce: u16,
447    pub stop_deceleration: u16,
448}
449impl FromByteSlice for GpioConfiguration {
450    fn bytes_expected() -> usize {
451        4
452    }
453    fn from_le_byte_slice(bytes: &[u8]) -> GpioConfiguration {
454        GpioConfiguration { debounce: <u16>::from_le_byte_slice(&bytes[0..2]), stop_deceleration: <u16>::from_le_byte_slice(&bytes[2..4]) }
455    }
456}
457
458#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
459pub struct AllDataEvent {
460    pub current_velocity: u16,
461    pub current_position: i32,
462    pub remaining_steps: i32,
463    pub input_voltage: u16,
464    pub current_consumption: u16,
465}
466impl FromByteSlice for AllDataEvent {
467    fn bytes_expected() -> usize {
468        14
469    }
470    fn from_le_byte_slice(bytes: &[u8]) -> AllDataEvent {
471        AllDataEvent {
472            current_velocity: <u16>::from_le_byte_slice(&bytes[0..2]),
473            current_position: <i32>::from_le_byte_slice(&bytes[2..6]),
474            remaining_steps: <i32>::from_le_byte_slice(&bytes[6..10]),
475            input_voltage: <u16>::from_le_byte_slice(&bytes[10..12]),
476            current_consumption: <u16>::from_le_byte_slice(&bytes[12..14]),
477        }
478    }
479}
480
481#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
482pub struct NewStateEvent {
483    pub state_new: u8,
484    pub state_previous: u8,
485}
486impl FromByteSlice for NewStateEvent {
487    fn bytes_expected() -> usize {
488        2
489    }
490    fn from_le_byte_slice(bytes: &[u8]) -> NewStateEvent {
491        NewStateEvent { state_new: <u8>::from_le_byte_slice(&bytes[0..1]), state_previous: <u8>::from_le_byte_slice(&bytes[1..2]) }
492    }
493}
494
495#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
496pub struct SpitfpErrorCount {
497    pub error_count_ack_checksum: u32,
498    pub error_count_message_checksum: u32,
499    pub error_count_frame: u32,
500    pub error_count_overflow: u32,
501}
502impl FromByteSlice for SpitfpErrorCount {
503    fn bytes_expected() -> usize {
504        16
505    }
506    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
507        SpitfpErrorCount {
508            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
509            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
510            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
511            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
512        }
513    }
514}
515
516#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
517pub struct Identity {
518    pub uid: String,
519    pub connected_uid: String,
520    pub position: char,
521    pub hardware_version: [u8; 3],
522    pub firmware_version: [u8; 3],
523    pub device_identifier: u16,
524}
525impl FromByteSlice for Identity {
526    fn bytes_expected() -> usize {
527        25
528    }
529    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
530        Identity {
531            uid: <String>::from_le_byte_slice(&bytes[0..8]),
532            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
533            position: <char>::from_le_byte_slice(&bytes[16..17]),
534            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
535            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
536            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
537        }
538    }
539}
540
541/// Silently drives one bipolar stepper motor with up to 46V and 1.6A per phase
542#[derive(Clone)]
543pub struct SilentStepperV2Bricklet {
544    device: Device,
545}
546impl SilentStepperV2Bricklet {
547    pub const DEVICE_IDENTIFIER: u16 = 2166;
548    pub const DEVICE_DISPLAY_NAME: &'static str = "Silent Stepper Bricklet 2.0";
549    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
550    pub fn new(uid: Uid, connection: AsyncIpConnection) -> SilentStepperV2Bricklet {
551        let mut result = SilentStepperV2Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
552        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetMaxVelocity) as usize] = ResponseExpectedFlag::False;
553        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetMaxVelocity) as usize] =
554            ResponseExpectedFlag::AlwaysTrue;
555        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetCurrentVelocity) as usize] =
556            ResponseExpectedFlag::AlwaysTrue;
557        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetSpeedRamping) as usize] = ResponseExpectedFlag::False;
558        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetSpeedRamping) as usize] =
559            ResponseExpectedFlag::AlwaysTrue;
560        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::FullBrake) as usize] = ResponseExpectedFlag::False;
561        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetCurrentPosition) as usize] =
562            ResponseExpectedFlag::False;
563        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetCurrentPosition) as usize] =
564            ResponseExpectedFlag::AlwaysTrue;
565        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetTargetPosition) as usize] =
566            ResponseExpectedFlag::False;
567        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetTargetPosition) as usize] =
568            ResponseExpectedFlag::AlwaysTrue;
569        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetSteps) as usize] = ResponseExpectedFlag::False;
570        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetSteps) as usize] = ResponseExpectedFlag::AlwaysTrue;
571        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetRemainingSteps) as usize] =
572            ResponseExpectedFlag::AlwaysTrue;
573        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetStepConfiguration) as usize] =
574            ResponseExpectedFlag::False;
575        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetStepConfiguration) as usize] =
576            ResponseExpectedFlag::AlwaysTrue;
577        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::DriveForward) as usize] = ResponseExpectedFlag::False;
578        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::DriveBackward) as usize] = ResponseExpectedFlag::False;
579        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::Stop) as usize] = ResponseExpectedFlag::False;
580        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetInputVoltage) as usize] =
581            ResponseExpectedFlag::AlwaysTrue;
582        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetMotorCurrent) as usize] = ResponseExpectedFlag::False;
583        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetMotorCurrent) as usize] =
584            ResponseExpectedFlag::AlwaysTrue;
585        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetEnabled) as usize] = ResponseExpectedFlag::False;
586        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetEnabled) as usize] = ResponseExpectedFlag::AlwaysTrue;
587        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetBasicConfiguration) as usize] =
588            ResponseExpectedFlag::False;
589        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetBasicConfiguration) as usize] =
590            ResponseExpectedFlag::AlwaysTrue;
591        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetSpreadcycleConfiguration) as usize] =
592            ResponseExpectedFlag::False;
593        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetSpreadcycleConfiguration) as usize] =
594            ResponseExpectedFlag::AlwaysTrue;
595        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetStealthConfiguration) as usize] =
596            ResponseExpectedFlag::False;
597        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetStealthConfiguration) as usize] =
598            ResponseExpectedFlag::AlwaysTrue;
599        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetCoolstepConfiguration) as usize] =
600            ResponseExpectedFlag::False;
601        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetCoolstepConfiguration) as usize] =
602            ResponseExpectedFlag::AlwaysTrue;
603        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetMiscConfiguration) as usize] =
604            ResponseExpectedFlag::False;
605        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetMiscConfiguration) as usize] =
606            ResponseExpectedFlag::AlwaysTrue;
607        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetErrorLedConfig) as usize] =
608            ResponseExpectedFlag::False;
609        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetErrorLedConfig) as usize] =
610            ResponseExpectedFlag::AlwaysTrue;
611        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetDriverStatus) as usize] =
612            ResponseExpectedFlag::AlwaysTrue;
613        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetMinimumVoltage) as usize] = ResponseExpectedFlag::True;
614        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetMinimumVoltage) as usize] =
615            ResponseExpectedFlag::AlwaysTrue;
616        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetTimeBase) as usize] = ResponseExpectedFlag::False;
617        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetTimeBase) as usize] = ResponseExpectedFlag::AlwaysTrue;
618        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetAllData) as usize] = ResponseExpectedFlag::AlwaysTrue;
619        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetAllCallbackConfiguration) as usize] =
620            ResponseExpectedFlag::True;
621        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetAllDataCallbackConfiguraton) as usize] =
622            ResponseExpectedFlag::AlwaysTrue;
623        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetGpioConfiguration) as usize] =
624            ResponseExpectedFlag::False;
625        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetGpioConfiguration) as usize] =
626            ResponseExpectedFlag::AlwaysTrue;
627        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetGpioAction) as usize] = ResponseExpectedFlag::False;
628        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetGpioAction) as usize] =
629            ResponseExpectedFlag::AlwaysTrue;
630        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetGpioState) as usize] =
631            ResponseExpectedFlag::AlwaysTrue;
632        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetSpitfpErrorCount) as usize] =
633            ResponseExpectedFlag::AlwaysTrue;
634        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetBootloaderMode) as usize] =
635            ResponseExpectedFlag::AlwaysTrue;
636        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetBootloaderMode) as usize] =
637            ResponseExpectedFlag::AlwaysTrue;
638        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetWriteFirmwarePointer) as usize] =
639            ResponseExpectedFlag::False;
640        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::WriteFirmware) as usize] =
641            ResponseExpectedFlag::AlwaysTrue;
642        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::SetStatusLedConfig) as usize] =
643            ResponseExpectedFlag::False;
644        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetStatusLedConfig) as usize] =
645            ResponseExpectedFlag::AlwaysTrue;
646        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetChipTemperature) as usize] =
647            ResponseExpectedFlag::AlwaysTrue;
648        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
649        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
650        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
651        result.device.response_expected[u8::from(SilentStepperV2BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
652        result
653    }
654
655    /// Returns the response expected flag for the function specified by the function ID parameter.
656    /// It is true if the function is expected to send a response, false otherwise.
657    ///
658    /// For getter functions this is enabled by default and cannot be disabled, because those
659    /// functions will always send a response. For callback configuration functions it is enabled
660    /// by default too, but can be disabled by [`set_response_expected`](crate::silent_stepper_v2_bricklet::SilentStepperV2Bricklet::set_response_expected).
661    /// For setter functions it is disabled by default and can be enabled.
662    ///
663    /// Enabling the response expected flag for a setter function allows to detect timeouts
664    /// and other error conditions calls of this setter as well. The device will then send a response
665    /// for this purpose. If this flag is disabled for a setter function then no response is sent
666    /// and errors are silently ignored, because they cannot be detected.
667    ///
668    /// See [`set_response_expected`](crate::silent_stepper_v2_bricklet::SilentStepperV2Bricklet::set_response_expected) for the list of function ID constants available for this function.
669    pub fn get_response_expected(&mut self, fun: SilentStepperV2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
670        self.device.get_response_expected(u8::from(fun))
671    }
672
673    /// Changes the response expected flag of the function specified by the function ID parameter.
674    /// This flag can only be changed for setter (default value: false) and callback configuration
675    /// functions (default value: true). For getter functions it is always enabled.
676    ///
677    /// Enabling the response expected flag for a setter function allows to detect timeouts and
678    /// other error conditions calls of this setter as well. The device will then send a response
679    /// for this purpose. If this flag is disabled for a setter function then no response is sent
680    /// and errors are silently ignored, because they cannot be detected.
681    pub fn set_response_expected(
682        &mut self,
683        fun: SilentStepperV2BrickletFunction,
684        response_expected: bool,
685    ) -> Result<(), SetResponseExpectedError> {
686        self.device.set_response_expected(u8::from(fun), response_expected)
687    }
688
689    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
690    pub fn set_response_expected_all(&mut self, response_expected: bool) {
691        self.device.set_response_expected_all(response_expected)
692    }
693
694    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
695    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
696    pub fn get_api_version(&self) -> [u8; 3] {
697        self.device.api_version
698    }
699
700    /// This receiver is triggered when the input voltage drops below the value set by
701    /// [`set_minimum_voltage`]. The parameter is the current voltage.
702    ///
703    /// [`set_minimum_voltage`]: #method.set_minimum_voltage
704    pub async fn get_under_voltage_callback_receiver(&mut self) -> impl Stream<Item = u16> {
705        self.device
706            .get_callback_receiver(u8::from(SilentStepperV2BrickletFunction::CallbackUnderVoltage))
707            .await
708            .map(|p| u16::from_le_byte_slice(p.body()))
709    }
710
711    /// This receiver is triggered when a position set by [`set_steps`] or
712    /// [`set_target_position`] is reached.
713    ///
714    /// # Note
715    ///  Since we can't get any feedback from the stepper motor, this only works if the
716    ///  acceleration (see [`set_speed_ramping`]) is set smaller or equal to the
717    ///  maximum acceleration of the motor. Otherwise the motor will lag behind the
718    ///  control value and the receiver will be triggered too early.
719    pub async fn get_position_reached_callback_receiver(&mut self) -> impl Stream<Item = i32> {
720        self.device
721            .get_callback_receiver(u8::from(SilentStepperV2BrickletFunction::CallbackPositionReached))
722            .await
723            .map(|p| i32::from_le_byte_slice(p.body()))
724    }
725
726    /// This receiver is triggered periodically with the period that is set by
727    /// [`set_all_callback_configuration`]. The parameters are: the current velocity,
728    /// the current position, the remaining steps, the stack voltage, the external
729    /// voltage and the current consumption of the stepper motor.
730    pub async fn get_all_data_callback_receiver(&mut self) -> impl Stream<Item = AllDataEvent> {
731        self.device
732            .get_callback_receiver(u8::from(SilentStepperV2BrickletFunction::CallbackAllData))
733            .await
734            .map(|p| AllDataEvent::from_le_byte_slice(p.body()))
735    }
736
737    /// This receiver is triggered whenever the Silent Stepper Bricklet 2.0 enters a new state.
738    /// It returns the new state as well as the previous state.
739    pub async fn get_new_state_callback_receiver(&mut self) -> impl Stream<Item = NewStateEvent> {
740        self.device
741            .get_callback_receiver(u8::from(SilentStepperV2BrickletFunction::CallbackNewState))
742            .await
743            .map(|p| NewStateEvent::from_le_byte_slice(p.body()))
744    }
745
746    /// This receiver is triggered by GPIO changes if it is activated through [`set_gpio_action`].
747    pub async fn get_gpio_state_callback_receiver(&mut self) -> impl Stream<Item = [bool; 2]> {
748        self.device
749            .get_callback_receiver(u8::from(SilentStepperV2BrickletFunction::CallbackGpioState))
750            .await
751            .map(|p| <[bool; 2]>::from_le_byte_slice(p.body()))
752    }
753
754    /// Sets the maximum velocity of the stepper motor.
755    /// This function does *not* start the motor, it merely sets the maximum
756    /// velocity the stepper motor is accelerated to. To get the motor running use
757    /// either [`set_target_position`], [`set_steps`], [`drive_forward`] or
758    /// [`drive_backward`].
759    pub async fn set_max_velocity(&mut self, velocity: u16) -> Result<(), TinkerforgeError> {
760        let mut payload = [0; 2];
761        velocity.write_to_slice(&mut payload[0..2]);
762
763        #[allow(unused_variables)]
764        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetMaxVelocity), &payload).await?;
765        Ok(())
766    }
767
768    /// Returns the velocity as set by [`set_max_velocity`].
769    pub async fn get_max_velocity(&mut self) -> Result<u16, TinkerforgeError> {
770        let payload = [0; 0];
771
772        #[allow(unused_variables)]
773        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetMaxVelocity), &payload).await?;
774        Ok(u16::from_le_byte_slice(result.body()))
775    }
776
777    /// Returns the *current* velocity of the stepper motor.
778    pub async fn get_current_velocity(&mut self) -> Result<u16, TinkerforgeError> {
779        let payload = [0; 0];
780
781        #[allow(unused_variables)]
782        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetCurrentVelocity), &payload).await?;
783        Ok(u16::from_le_byte_slice(result.body()))
784    }
785
786    /// Sets the acceleration and deacceleration of the stepper motor.
787    /// An acceleration of 1000 means, that
788    /// every second the velocity is increased by 1000 *steps/s*.
789    ///
790    /// For example: If the current velocity is 0 and you want to accelerate to a
791    /// velocity of 8000 *steps/s* in 10 seconds, you should set an acceleration
792    /// of 800 *steps/s²*.
793    ///
794    /// An acceleration/deacceleration of 0 means instantaneous
795    /// acceleration/deacceleration (not recommended)
796    pub async fn set_speed_ramping(&mut self, acceleration: u16, deacceleration: u16) -> Result<(), TinkerforgeError> {
797        let mut payload = [0; 4];
798        acceleration.write_to_slice(&mut payload[0..2]);
799        deacceleration.write_to_slice(&mut payload[2..4]);
800
801        #[allow(unused_variables)]
802        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetSpeedRamping), &payload).await?;
803        Ok(())
804    }
805
806    /// Returns the acceleration and deacceleration as set by
807    /// [`set_speed_ramping`].
808    pub async fn get_speed_ramping(&mut self) -> Result<SpeedRamping, TinkerforgeError> {
809        let payload = [0; 0];
810
811        #[allow(unused_variables)]
812        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetSpeedRamping), &payload).await?;
813        Ok(SpeedRamping::from_le_byte_slice(result.body()))
814    }
815
816    /// Executes an active full brake.
817    ///
818    /// # Warning
819    ///  This function is for emergency purposes,
820    ///  where an immediate brake is necessary. Depending on the current velocity and
821    ///  the strength of the motor, a full brake can be quite violent.
822    ///
823    /// Call [`stop`] if you just want to stop the motor.
824    pub async fn full_brake(&mut self) -> Result<(), TinkerforgeError> {
825        let payload = [0; 0];
826
827        #[allow(unused_variables)]
828        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::FullBrake), &payload).await?;
829        Ok(())
830    }
831
832    /// Sets the current steps of the internal step counter. This can be used to
833    /// set the current position to 0 when some kind of starting position
834    /// is reached (e.g. when a CNC machine reaches a corner).
835    pub async fn set_current_position(&mut self, position: i32) -> Result<(), TinkerforgeError> {
836        let mut payload = [0; 4];
837        position.write_to_slice(&mut payload[0..4]);
838
839        #[allow(unused_variables)]
840        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetCurrentPosition), &payload).await?;
841        Ok(())
842    }
843
844    /// Returns the current position of the stepper motor in steps. On startup
845    /// the position is 0. The steps are counted with all possible driving
846    /// functions ([`set_target_position`], [`set_steps`], [`drive_forward`] or
847    /// [`drive_backward`]). It also is possible to reset the steps to 0 or
848    /// set them to any other desired value with [`set_current_position`].
849    pub async fn get_current_position(&mut self) -> Result<i32, TinkerforgeError> {
850        let payload = [0; 0];
851
852        #[allow(unused_variables)]
853        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetCurrentPosition), &payload).await?;
854        Ok(i32::from_le_byte_slice(result.body()))
855    }
856
857    /// Sets the target position of the stepper motor in steps. For example,
858    /// if the current position of the motor is 500 and [`set_target_position`] is
859    /// called with 1000, the stepper motor will drive 500 steps forward. It will
860    /// use the velocity, acceleration and deacceleration as set by
861    /// [`set_max_velocity`] and [`set_speed_ramping`].
862    ///
863    /// A call of [`set_target_position`] with the parameter *x* is equivalent to
864    /// a call of [`set_steps`] with the parameter
865    /// (*x* - [`get_current_position`]).
866    pub async fn set_target_position(&mut self, position: i32) -> Result<(), TinkerforgeError> {
867        let mut payload = [0; 4];
868        position.write_to_slice(&mut payload[0..4]);
869
870        #[allow(unused_variables)]
871        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetTargetPosition), &payload).await?;
872        Ok(())
873    }
874
875    /// Returns the last target position as set by [`set_target_position`].
876    pub async fn get_target_position(&mut self) -> Result<i32, TinkerforgeError> {
877        let payload = [0; 0];
878
879        #[allow(unused_variables)]
880        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetTargetPosition), &payload).await?;
881        Ok(i32::from_le_byte_slice(result.body()))
882    }
883
884    /// Sets the number of steps the stepper motor should run. Positive values
885    /// will drive the motor forward and negative values backward.
886    /// The velocity, acceleration and deacceleration as set by
887    /// [`set_max_velocity`] and [`set_speed_ramping`] will be used.
888    pub async fn set_steps(&mut self, steps: i32) -> Result<(), TinkerforgeError> {
889        let mut payload = [0; 4];
890        steps.write_to_slice(&mut payload[0..4]);
891
892        #[allow(unused_variables)]
893        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetSteps), &payload).await?;
894        Ok(())
895    }
896
897    /// Returns the last steps as set by [`set_steps`].
898    pub async fn get_steps(&mut self) -> Result<i32, TinkerforgeError> {
899        let payload = [0; 0];
900
901        #[allow(unused_variables)]
902        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetSteps), &payload).await?;
903        Ok(i32::from_le_byte_slice(result.body()))
904    }
905
906    /// Returns the remaining steps of the last call of [`set_steps`].
907    /// For example, if [`set_steps`] is called with 2000 and
908    /// [`get_remaining_steps`] is called after the motor has run for 500 steps,
909    /// it will return 1500.
910    pub async fn get_remaining_steps(&mut self) -> Result<i32, TinkerforgeError> {
911        let payload = [0; 0];
912
913        #[allow(unused_variables)]
914        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetRemainingSteps), &payload).await?;
915        Ok(i32::from_le_byte_slice(result.body()))
916    }
917
918    /// Sets the step resolution from full-step up to 1/256-step.
919    ///
920    /// If interpolation is turned on, the Silent Stepper Bricklet 2.0 will always interpolate
921    /// your step inputs as 1/256-step. If you use full-step mode with interpolation, each
922    /// step will generate 256 1/256 steps.
923    ///
924    /// For maximum torque use full-step without interpolation. For maximum resolution use
925    /// 1/256-step. Turn interpolation on to make the Stepper driving less noisy.
926    ///
927    /// If you often change the speed with high acceleration you should turn the
928    /// interpolation off.
929    ///
930    /// Associated constants:
931    /// * SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_1
932    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_2
933    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_4
934    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_8
935    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_16
936    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_32
937    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_64
938    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_128
939    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_256
940    pub async fn set_step_configuration(&mut self, step_resolution: u8, interpolation: bool) -> Result<(), TinkerforgeError> {
941        let mut payload = [0; 2];
942        step_resolution.write_to_slice(&mut payload[0..1]);
943        interpolation.write_to_slice(&mut payload[1..2]);
944
945        #[allow(unused_variables)]
946        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetStepConfiguration), &payload).await?;
947        Ok(())
948    }
949
950    /// Returns the step mode as set by [`set_step_configuration`].
951    ///
952    /// Associated constants:
953    /// * SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_1
954    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_2
955    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_4
956    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_8
957    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_16
958    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_32
959    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_64
960    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_128
961    ///	* SILENT_STEPPER_V2_BRICKLET_STEP_RESOLUTION_256
962    pub async fn get_step_configuration(&mut self) -> Result<StepConfiguration, TinkerforgeError> {
963        let payload = [0; 0];
964
965        #[allow(unused_variables)]
966        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetStepConfiguration), &payload).await?;
967        Ok(StepConfiguration::from_le_byte_slice(result.body()))
968    }
969
970    /// Drives the stepper motor forward until [`drive_backward`] or
971    /// [`stop`] is called. The velocity, acceleration and deacceleration as
972    /// set by [`set_max_velocity`] and [`set_speed_ramping`] will be used.
973    pub async fn drive_forward(&mut self) -> Result<(), TinkerforgeError> {
974        let payload = [0; 0];
975
976        #[allow(unused_variables)]
977        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::DriveForward), &payload).await?;
978        Ok(())
979    }
980
981    /// Drives the stepper motor backward until [`drive_forward`] or
982    /// [`stop`] is triggered. The velocity, acceleration and deacceleration as
983    /// set by [`set_max_velocity`] and [`set_speed_ramping`] will be used.
984    pub async fn drive_backward(&mut self) -> Result<(), TinkerforgeError> {
985        let payload = [0; 0];
986
987        #[allow(unused_variables)]
988        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::DriveBackward), &payload).await?;
989        Ok(())
990    }
991
992    /// Stops the stepper motor with the deacceleration as set by
993    /// [`set_speed_ramping`].
994    pub async fn stop(&mut self) -> Result<(), TinkerforgeError> {
995        let payload = [0; 0];
996
997        #[allow(unused_variables)]
998        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::Stop), &payload).await?;
999        Ok(())
1000    }
1001
1002    /// Returns the external input voltage. The external input voltage is
1003    /// given via the black power input connector on the Silent Stepper Bricklet 2.0.
1004    ///
1005    /// If there is an external input voltage and a stack input voltage, the motor
1006    /// will be driven by the external input voltage. If there is only a stack
1007    /// voltage present, the motor will be driven by this voltage.
1008    ///
1009    /// # Warning
1010    ///  This means, if you have a high stack voltage and a low external voltage,
1011    ///  the motor will be driven with the low external voltage. If you then remove
1012    ///  the external connection, it will immediately be driven by the high
1013    ///  stack voltage
1014    pub async fn get_input_voltage(&mut self) -> Result<u16, TinkerforgeError> {
1015        let payload = [0; 0];
1016
1017        #[allow(unused_variables)]
1018        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetInputVoltage), &payload).await?;
1019        Ok(u16::from_le_byte_slice(result.body()))
1020    }
1021
1022    /// Sets the current with which the motor will be driven.
1023    ///
1024    /// # Warning
1025    ///  Do not set this value above the specifications of your stepper motor.
1026    ///  Otherwise it may damage your motor.
1027    pub async fn set_motor_current(&mut self, current: u16) -> Result<(), TinkerforgeError> {
1028        let mut payload = [0; 2];
1029        current.write_to_slice(&mut payload[0..2]);
1030
1031        #[allow(unused_variables)]
1032        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetMotorCurrent), &payload).await?;
1033        Ok(())
1034    }
1035
1036    /// Returns the current as set by [`set_motor_current`].
1037    pub async fn get_motor_current(&mut self) -> Result<u16, TinkerforgeError> {
1038        let payload = [0; 0];
1039
1040        #[allow(unused_variables)]
1041        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetMotorCurrent), &payload).await?;
1042        Ok(u16::from_le_byte_slice(result.body()))
1043    }
1044
1045    /// Enables/Disables the driver chip. The driver parameters can be configured (maximum velocity,
1046    /// acceleration, etc) before it is enabled.
1047    ///
1048    /// # Warning
1049    ///  Disabling the driver chip while the motor is still turning can damage the
1050    ///  driver chip. The motor should be stopped calling [`stop`] function
1051    ///  before disabling the motor power. The [`stop`] function will **not**
1052    ///  wait until the motor is actually stopped. You have to explicitly wait for the
1053    ///  appropriate time after calling the [`stop`] function before calling
1054    ///  the [`set_enabled`] with false function.
1055    pub async fn set_enabled(&mut self, enabled: bool) -> Result<(), TinkerforgeError> {
1056        let mut payload = [0; 1];
1057        enabled.write_to_slice(&mut payload[0..1]);
1058
1059        #[allow(unused_variables)]
1060        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetEnabled), &payload).await?;
1061        Ok(())
1062    }
1063
1064    /// Returns *true* if the stepper driver is enabled, *false* otherwise.
1065    pub async fn get_enabled(&mut self) -> Result<bool, TinkerforgeError> {
1066        let payload = [0; 0];
1067
1068        #[allow(unused_variables)]
1069        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetEnabled), &payload).await?;
1070        Ok(bool::from_le_byte_slice(result.body()))
1071    }
1072
1073    /// Sets the basic configuration parameters for the different modes (Stealth, Coolstep, Classic).
1074    ///
1075    /// * Standstill Current: This value can be used to lower the current during stand still. This might
1076    ///   be reasonable to reduce the heating of the motor and the Bricklet 2.0. When the motor is in standstill
1077    ///   the configured motor phase current will be driven until the configured
1078    ///   Power Down Time is elapsed. After that the phase current will be reduced to the standstill
1079    ///   current. The elapsed time for this reduction can be configured with the Standstill Delay Time.
1080    ///   The maximum allowed value is the configured maximum motor current
1081    ///   (see [`set_motor_current`]).
1082    ///
1083    /// * Motor Run Current: The value sets the motor current when the motor is running.
1084    ///   Use a value of at least one half of the global maximum motor current for a good
1085    ///   microstep performance. The maximum allowed value is the current
1086    ///   motor current. The API maps the entered value to 1/32 ... 32/32 of the maximum
1087    ///   motor current. This value should be used to change the motor current during motor movement,
1088    ///   whereas the global maximum motor current should not be changed while the motor is moving
1089    ///   (see [`set_motor_current`]).
1090    ///
1091    /// * Standstill Delay Time: Controls the duration for motor power down after a motion
1092    ///   as soon as standstill is detected and the Power Down Time is expired. A high Standstill Delay
1093    ///   Time results in a smooth transition that avoids motor jerk during power down.
1094    ///
1095    /// * Power Down Time: Sets the delay time after a stand still.
1096    ///
1097    /// * Stealth Threshold: Sets the upper threshold for Stealth mode.
1098    ///   If the velocity of the motor goes above this value, Stealth mode is turned
1099    ///   off. Otherwise it is turned on. In Stealth mode the torque declines with high speed.
1100    ///
1101    /// * Coolstep Threshold: Sets the lower threshold for Coolstep mode.
1102    ///   The Coolstep Threshold needs to be above the Stealth Threshold.
1103    ///
1104    /// * Classic Threshold: Sets the lower threshold for classic mode.
1105    ///   In classic mode the stepper becomes more noisy, but the torque is maximized.
1106    ///
1107    /// * High Velocity Chopper Mode: If High Velocity Chopper Mode is enabled, the stepper control
1108    ///   is optimized to run the stepper motors at high velocities.
1109    ///
1110    /// If you want to use all three thresholds make sure that
1111    /// Stealth Threshold < Coolstep Threshold < Classic Threshold.
1112    pub async fn set_basic_configuration(
1113        &mut self,
1114        standstill_current: u16,
1115        motor_run_current: u16,
1116        standstill_delay_time: u16,
1117        power_down_time: u16,
1118        stealth_threshold: u16,
1119        coolstep_threshold: u16,
1120        classic_threshold: u16,
1121        high_velocity_chopper_mode: bool,
1122    ) -> Result<(), TinkerforgeError> {
1123        let mut payload = [0; 15];
1124        standstill_current.write_to_slice(&mut payload[0..2]);
1125        motor_run_current.write_to_slice(&mut payload[2..4]);
1126        standstill_delay_time.write_to_slice(&mut payload[4..6]);
1127        power_down_time.write_to_slice(&mut payload[6..8]);
1128        stealth_threshold.write_to_slice(&mut payload[8..10]);
1129        coolstep_threshold.write_to_slice(&mut payload[10..12]);
1130        classic_threshold.write_to_slice(&mut payload[12..14]);
1131        high_velocity_chopper_mode.write_to_slice(&mut payload[14..15]);
1132
1133        #[allow(unused_variables)]
1134        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetBasicConfiguration), &payload).await?;
1135        Ok(())
1136    }
1137
1138    /// Returns the configuration as set by [`set_basic_configuration`].
1139    pub async fn get_basic_configuration(&mut self) -> Result<BasicConfiguration, TinkerforgeError> {
1140        let payload = [0; 0];
1141
1142        #[allow(unused_variables)]
1143        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetBasicConfiguration), &payload).await?;
1144        Ok(BasicConfiguration::from_le_byte_slice(result.body()))
1145    }
1146
1147    /// Note: If you don't know what any of this means you can very likely keep all of
1148    /// the values as default!
1149    ///
1150    /// Sets the Spreadcycle configuration parameters. Spreadcycle is a chopper algorithm which actively
1151    /// controls the motor current flow. More information can be found in the TMC2130 datasheet on page
1152    /// 47 (7 spreadCycle and Classic Chopper).
1153    ///
1154    /// * Slow Decay Duration: Controls duration of off time setting of slow decay phase.
1155    ///   0 = driver disabled, all bridges off. Use 1 only with Comparator Blank time >= 2.
1156    ///
1157    /// * Enable Random Slow Decay: Set to false to fix chopper off time as set by Slow Decay Duration.
1158    ///   If you set it to true, Decay Duration is randomly modulated.
1159    ///
1160    /// * Fast Decay Duration: Sets the fast decay duration. This parameters is
1161    ///   only used if the Chopper Mode is set to Fast Decay.
1162    ///
1163    /// * Hysteresis Start Value: Sets the hysteresis start value. This parameter is
1164    ///   only used if the Chopper Mode is set to Spread Cycle.
1165    ///
1166    /// * Hysteresis End Value: Sets the hysteresis end value. This parameter is
1167    ///   only used if the Chopper Mode is set to Spread Cycle.
1168    ///
1169    /// * Sine Wave Offset: Sets the sine wave offset. This parameters is
1170    ///   only used if the Chopper Mode is set to Fast Decay. 1/512 of the value becomes added to the absolute
1171    ///   value of the sine wave.
1172    ///
1173    /// * Chopper Mode: 0 = Spread Cycle, 1 = Fast Decay.
1174    ///
1175    /// * Comparator Blank Time: Sets the blank time of the comparator. Available values are
1176    ///
1177    ///   * 0 = 16 clocks,
1178    ///   * 1 = 24 clocks,
1179    ///   * 2 = 36 clocks and
1180    ///   * 3 = 54 clocks.
1181    ///
1182    ///   A value of 1 or 2 is recommended for most applications.
1183    ///
1184    /// * Fast Decay Without Comparator: If set to true the current comparator usage for termination of the
1185    ///   fast decay cycle is disabled.
1186    ///
1187    /// Associated constants:
1188    /// * SILENT_STEPPER_V2_BRICKLET_CHOPPER_MODE_SPREAD_CYCLE
1189    ///	* SILENT_STEPPER_V2_BRICKLET_CHOPPER_MODE_FAST_DECAY
1190    pub async fn set_spreadcycle_configuration(
1191        &mut self,
1192        slow_decay_duration: u8,
1193        enable_random_slow_decay: bool,
1194        fast_decay_duration: u8,
1195        hysteresis_start_value: u8,
1196        hysteresis_end_value: i8,
1197        sine_wave_offset: i8,
1198        chopper_mode: u8,
1199        comparator_blank_time: u8,
1200        fast_decay_without_comparator: bool,
1201    ) -> Result<(), TinkerforgeError> {
1202        let mut payload = [0; 9];
1203        slow_decay_duration.write_to_slice(&mut payload[0..1]);
1204        enable_random_slow_decay.write_to_slice(&mut payload[1..2]);
1205        fast_decay_duration.write_to_slice(&mut payload[2..3]);
1206        hysteresis_start_value.write_to_slice(&mut payload[3..4]);
1207        hysteresis_end_value.write_to_slice(&mut payload[4..5]);
1208        sine_wave_offset.write_to_slice(&mut payload[5..6]);
1209        chopper_mode.write_to_slice(&mut payload[6..7]);
1210        comparator_blank_time.write_to_slice(&mut payload[7..8]);
1211        fast_decay_without_comparator.write_to_slice(&mut payload[8..9]);
1212
1213        #[allow(unused_variables)]
1214        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetSpreadcycleConfiguration), &payload).await?;
1215        Ok(())
1216    }
1217
1218    /// Returns the configuration as set by [`set_basic_configuration`].
1219    ///
1220    /// Associated constants:
1221    /// * SILENT_STEPPER_V2_BRICKLET_CHOPPER_MODE_SPREAD_CYCLE
1222    ///	* SILENT_STEPPER_V2_BRICKLET_CHOPPER_MODE_FAST_DECAY
1223    pub async fn get_spreadcycle_configuration(&mut self) -> Result<SpreadcycleConfiguration, TinkerforgeError> {
1224        let payload = [0; 0];
1225
1226        #[allow(unused_variables)]
1227        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetSpreadcycleConfiguration), &payload).await?;
1228        Ok(SpreadcycleConfiguration::from_le_byte_slice(result.body()))
1229    }
1230
1231    /// Note: If you don't know what any of this means you can very likely keep all of
1232    /// the values as default!
1233    ///
1234    /// Sets the configuration relevant for Stealth mode.
1235    ///
1236    /// * Enable Stealth: If set to true the stealth mode is enabled, if set to false the
1237    ///   stealth mode is disabled, even if the speed is below the threshold set in [`set_basic_configuration`].
1238    ///
1239    /// * Amplitude: If autoscale is disabled, the PWM amplitude is scaled by this value. If autoscale is enabled,
1240    ///   this value defines the maximum PWM amplitude change per half wave.
1241    ///
1242    /// * Gradient: If autoscale is disabled, the PWM gradient is scaled by this value. If autoscale is enabled,
1243    ///   this value defines the maximum PWM gradient. With autoscale a value above 64 is recommended,
1244    ///   otherwise the regulation might not be able to measure the current.
1245    ///
1246    /// * Enable Autoscale: If set to true, automatic current control is used. Otherwise the user defined
1247    ///   amplitude and gradient are used.
1248    ///
1249    /// * Force Symmetric: If true, A symmetric PWM cycle is enforced. Otherwise the PWM value may change within each
1250    ///   PWM cycle.
1251    ///
1252    /// * Freewheel Mode: The freewheel mode defines the behavior in stand still if the Standstill Current
1253    ///   (see [`set_basic_configuration`]) is set to 0.
1254    ///
1255    /// Associated constants:
1256    /// * SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_NORMAL
1257    ///	* SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_FREEWHEELING
1258    ///	* SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_COIL_SHORT_LS
1259    ///	* SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_COIL_SHORT_HS
1260    pub async fn set_stealth_configuration(
1261        &mut self,
1262        enable_stealth: bool,
1263        amplitude: u8,
1264        gradient: u8,
1265        enable_autoscale: bool,
1266        force_symmetric: bool,
1267        freewheel_mode: u8,
1268    ) -> Result<(), TinkerforgeError> {
1269        let mut payload = [0; 6];
1270        enable_stealth.write_to_slice(&mut payload[0..1]);
1271        amplitude.write_to_slice(&mut payload[1..2]);
1272        gradient.write_to_slice(&mut payload[2..3]);
1273        enable_autoscale.write_to_slice(&mut payload[3..4]);
1274        force_symmetric.write_to_slice(&mut payload[4..5]);
1275        freewheel_mode.write_to_slice(&mut payload[5..6]);
1276
1277        #[allow(unused_variables)]
1278        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetStealthConfiguration), &payload).await?;
1279        Ok(())
1280    }
1281
1282    /// Returns the configuration as set by [`set_stealth_configuration`].
1283    ///
1284    /// Associated constants:
1285    /// * SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_NORMAL
1286    ///	* SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_FREEWHEELING
1287    ///	* SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_COIL_SHORT_LS
1288    ///	* SILENT_STEPPER_V2_BRICKLET_FREEWHEEL_MODE_COIL_SHORT_HS
1289    pub async fn get_stealth_configuration(&mut self) -> Result<StealthConfiguration, TinkerforgeError> {
1290        let payload = [0; 0];
1291
1292        #[allow(unused_variables)]
1293        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetStealthConfiguration), &payload).await?;
1294        Ok(StealthConfiguration::from_le_byte_slice(result.body()))
1295    }
1296
1297    /// Note: If you don't know what any of this means you can very likely keep all of
1298    /// the values as default!
1299    ///
1300    /// Sets the configuration relevant for Coolstep.
1301    ///
1302    /// * Minimum Stallguard Value: If the Stallguard result falls below this value*32, the motor current
1303    ///   is increased to reduce motor load angle. A value of 0 turns Coolstep off.
1304    ///
1305    /// * Maximum Stallguard Value: If the Stallguard result goes above
1306    ///   (Min Stallguard Value + Max Stallguard Value + 1) * 32, the motor current is decreased to save
1307    ///   energy.
1308    ///
1309    /// * Current Up Step Width: Sets the up step increment per Stallguard value. The value range is 0-3,
1310    ///   corresponding to the increments 1, 2, 4 and 8.
1311    ///
1312    /// * Current Down Step Width: Sets the down step decrement per Stallguard value. The value range is 0-3,
1313    ///   corresponding to the decrements 1, 2, 8 and 16.
1314    ///
1315    /// * Minimum Current: Sets the minimum current for Coolstep current control. You can choose between
1316    ///   half and quarter of the run current.
1317    ///
1318    /// * Stallguard Threshold Value: Sets the level for stall output (see [`get_driver_status`]).
1319    ///   A lower value gives a higher sensitivity. You have to find a suitable value for your
1320    ///   motor by trial and error, 0 works for most motors.
1321    ///
1322    /// * Stallguard Mode: Set to 0 for standard resolution or 1 for filtered mode. In filtered mode the Stallguard
1323    ///   signal will be updated every four full-steps.
1324    ///
1325    /// Associated constants:
1326    /// * SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_1
1327    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_2
1328    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_4
1329    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_8
1330    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_1
1331    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_2
1332    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_8
1333    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_32
1334    ///	* SILENT_STEPPER_V2_BRICKLET_MINIMUM_CURRENT_HALF
1335    ///	* SILENT_STEPPER_V2_BRICKLET_MINIMUM_CURRENT_QUARTER
1336    ///	* SILENT_STEPPER_V2_BRICKLET_STALLGUARD_MODE_STANDARD
1337    ///	* SILENT_STEPPER_V2_BRICKLET_STALLGUARD_MODE_FILTERED
1338    pub async fn set_coolstep_configuration(
1339        &mut self,
1340        minimum_stallguard_value: u8,
1341        maximum_stallguard_value: u8,
1342        current_up_step_width: u8,
1343        current_down_step_width: u8,
1344        minimum_current: u8,
1345        stallguard_threshold_value: i8,
1346        stallguard_mode: u8,
1347    ) -> Result<(), TinkerforgeError> {
1348        let mut payload = [0; 7];
1349        minimum_stallguard_value.write_to_slice(&mut payload[0..1]);
1350        maximum_stallguard_value.write_to_slice(&mut payload[1..2]);
1351        current_up_step_width.write_to_slice(&mut payload[2..3]);
1352        current_down_step_width.write_to_slice(&mut payload[3..4]);
1353        minimum_current.write_to_slice(&mut payload[4..5]);
1354        stallguard_threshold_value.write_to_slice(&mut payload[5..6]);
1355        stallguard_mode.write_to_slice(&mut payload[6..7]);
1356
1357        #[allow(unused_variables)]
1358        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetCoolstepConfiguration), &payload).await?;
1359        Ok(())
1360    }
1361
1362    /// Returns the configuration as set by [`set_coolstep_configuration`].
1363    ///
1364    /// Associated constants:
1365    /// * SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_1
1366    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_2
1367    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_4
1368    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_UP_STEP_INCREMENT_8
1369    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_1
1370    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_2
1371    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_8
1372    ///	* SILENT_STEPPER_V2_BRICKLET_CURRENT_DOWN_STEP_DECREMENT_32
1373    ///	* SILENT_STEPPER_V2_BRICKLET_MINIMUM_CURRENT_HALF
1374    ///	* SILENT_STEPPER_V2_BRICKLET_MINIMUM_CURRENT_QUARTER
1375    ///	* SILENT_STEPPER_V2_BRICKLET_STALLGUARD_MODE_STANDARD
1376    ///	* SILENT_STEPPER_V2_BRICKLET_STALLGUARD_MODE_FILTERED
1377    pub async fn get_coolstep_configuration(&mut self) -> Result<CoolstepConfiguration, TinkerforgeError> {
1378        let payload = [0; 0];
1379
1380        #[allow(unused_variables)]
1381        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetCoolstepConfiguration), &payload).await?;
1382        Ok(CoolstepConfiguration::from_le_byte_slice(result.body()))
1383    }
1384
1385    /// Note: If you don't know what any of this means you can very likely keep all of
1386    /// the values as default!
1387    ///
1388    /// Sets miscellaneous configuration parameters.
1389    ///
1390    /// * Disable Short To Ground Protection: Set to false to enable short to ground protection, otherwise
1391    ///   it is disabled.
1392    ///
1393    /// * Synchronize Phase Frequency: With this parameter you can synchronize the chopper for both phases
1394    ///   of a two phase motor to avoid the occurrence of a beat. The value range is 0-15. If set to 0,
1395    ///   the synchronization is turned off. Otherwise the synchronization is done through the formula
1396    ///   f_sync = f_clk/(value*64). In Classic Mode the synchronization is automatically switched off.
1397    ///   f_clk is 12.8MHz.
1398    pub async fn set_misc_configuration(
1399        &mut self,
1400        disable_short_to_ground_protection: bool,
1401        synchronize_phase_frequency: u8,
1402    ) -> Result<(), TinkerforgeError> {
1403        let mut payload = [0; 2];
1404        disable_short_to_ground_protection.write_to_slice(&mut payload[0..1]);
1405        synchronize_phase_frequency.write_to_slice(&mut payload[1..2]);
1406
1407        #[allow(unused_variables)]
1408        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetMiscConfiguration), &payload).await?;
1409        Ok(())
1410    }
1411
1412    /// Returns the configuration as set by [`set_misc_configuration`].
1413    pub async fn get_misc_configuration(&mut self) -> Result<MiscConfiguration, TinkerforgeError> {
1414        let payload = [0; 0];
1415
1416        #[allow(unused_variables)]
1417        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetMiscConfiguration), &payload).await?;
1418        Ok(MiscConfiguration::from_le_byte_slice(result.body()))
1419    }
1420
1421    /// Configures the error LED to be either turned off, turned on, blink in
1422    /// heartbeat mode or show an error.
1423    ///
1424    /// If the LED is configured to show errors it has three different states:
1425    ///
1426    /// * Off: No error present.
1427    /// * 250ms interval blink: Overtemperature warning.
1428    /// * 1s interval blink: Input voltage too small.
1429    /// * full red: motor disabled because of short to ground in phase a or b or because of overtemperature.
1430    ///
1431    /// Associated constants:
1432    /// * SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_OFF
1433    ///	* SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_ON
1434    ///	* SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT
1435    ///	* SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR
1436    pub async fn set_error_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
1437        let mut payload = [0; 1];
1438        config.write_to_slice(&mut payload[0..1]);
1439
1440        #[allow(unused_variables)]
1441        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetErrorLedConfig), &payload).await?;
1442        Ok(())
1443    }
1444
1445    /// Returns the LED configuration as set by [`set_error_led_config`]
1446    ///
1447    /// Associated constants:
1448    /// * SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_OFF
1449    ///	* SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_ON
1450    ///	* SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT
1451    ///	* SILENT_STEPPER_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR
1452    pub async fn get_error_led_config(&mut self) -> Result<u8, TinkerforgeError> {
1453        let payload = [0; 0];
1454
1455        #[allow(unused_variables)]
1456        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetErrorLedConfig), &payload).await?;
1457        Ok(u8::from_le_byte_slice(result.body()))
1458    }
1459
1460    /// Returns the current driver status.
1461    ///
1462    /// * Open Load: Indicates if an open load is present on phase A, B or both. This could mean that there is a problem
1463    ///   with the wiring of the motor. False detection can occur in fast motion as well as during stand still.
1464    ///
1465    /// * Short To Ground: Indicates if a short to ground is present on phase A, B or both. If this is detected the driver
1466    ///   automatically becomes disabled and stays disabled until it is enabled again manually.
1467    ///
1468    /// * Over Temperature: The over temperature indicator switches to Warning if the driver IC warms up. The warning flag
1469    ///   is expected during long duration stepper uses. If the temperature limit is reached the indicator switches
1470    ///   to Limit. In this case the driver becomes disabled until it cools down again.
1471    ///
1472    /// * Motor Stalled: Is true if a motor stall was detected.
1473    ///
1474    /// * Actual Motor Current: Indicates the actual current control scaling as used in Coolstep mode.
1475    ///   It represents a multiplier of 1/32 to 32/32 of the
1476    ///   ``Motor Run Current`` as set by [`set_basic_configuration`]. Example: If a ``Motor Run Current``
1477    ///   of 1000mA was set and the returned value is 15, the ``Actual Motor Current`` is 16/32*1000mA = 500mA.
1478    ///
1479    /// * Stallguard Result: Indicates the load of the motor. A lower value signals a higher load. Per trial and error
1480    ///   you can find out which value corresponds to a suitable torque for the velocity used in your application.
1481    ///   After that you can use this threshold value to find out if a motor stall becomes probable and react on it (e.g.
1482    ///   decrease velocity).
1483    ///   During stand still this value can not be used for stall detection, it shows the chopper on-time for motor coil A.
1484    ///
1485    /// * Stealth Voltage Amplitude: Shows the actual PWM scaling. In Stealth mode it can be used to detect motor load and
1486    ///   stall if autoscale is enabled (see [`set_stealth_configuration`]).
1487    ///
1488    /// Associated constants:
1489    /// * SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_NONE
1490    ///	* SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_PHASE_A
1491    ///	* SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_PHASE_B
1492    ///	* SILENT_STEPPER_V2_BRICKLET_OPEN_LOAD_PHASE_AB
1493    ///	* SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_NONE
1494    ///	* SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_PHASE_A
1495    ///	* SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_PHASE_B
1496    ///	* SILENT_STEPPER_V2_BRICKLET_SHORT_TO_GROUND_PHASE_AB
1497    ///	* SILENT_STEPPER_V2_BRICKLET_OVER_TEMPERATURE_NONE
1498    ///	* SILENT_STEPPER_V2_BRICKLET_OVER_TEMPERATURE_WARNING
1499    ///	* SILENT_STEPPER_V2_BRICKLET_OVER_TEMPERATURE_LIMIT
1500    pub async fn get_driver_status(&mut self) -> Result<DriverStatus, TinkerforgeError> {
1501        let payload = [0; 0];
1502
1503        #[allow(unused_variables)]
1504        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetDriverStatus), &payload).await?;
1505        Ok(DriverStatus::from_le_byte_slice(result.body()))
1506    }
1507
1508    /// Sets the minimum voltage, below which the [`get_under_voltage_callback_receiver`] receiver
1509    /// is triggered. The minimum possible value that works with the Silent Stepper
1510    /// Bricklet 2.0 is 8V.
1511    /// You can use this function to detect the discharge of a battery that is used
1512    /// to drive the stepper motor. If you have a fixed power supply, you likely do
1513    /// not need this functionality.
1514    pub async fn set_minimum_voltage(&mut self, voltage: u16) -> Result<(), TinkerforgeError> {
1515        let mut payload = [0; 2];
1516        voltage.write_to_slice(&mut payload[0..2]);
1517
1518        #[allow(unused_variables)]
1519        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetMinimumVoltage), &payload).await?;
1520        Ok(())
1521    }
1522
1523    /// Returns the minimum voltage as set by [`set_minimum_voltage`].
1524    pub async fn get_minimum_voltage(&mut self) -> Result<u16, TinkerforgeError> {
1525        let payload = [0; 0];
1526
1527        #[allow(unused_variables)]
1528        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetMinimumVoltage), &payload).await?;
1529        Ok(u16::from_le_byte_slice(result.body()))
1530    }
1531
1532    /// Sets the time base of the velocity and the acceleration of the Silent Stepper
1533    /// Bricklet 2.0.
1534    ///
1535    /// For example, if you want to make one step every 1.5 seconds, you can set
1536    /// the time base to 15 and the velocity to 10. Now the velocity is
1537    /// 10steps/15s = 1steps/1.5s.
1538    pub async fn set_time_base(&mut self, time_base: u32) -> Result<(), TinkerforgeError> {
1539        let mut payload = [0; 4];
1540        time_base.write_to_slice(&mut payload[0..4]);
1541
1542        #[allow(unused_variables)]
1543        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetTimeBase), &payload).await?;
1544        Ok(())
1545    }
1546
1547    /// Returns the time base as set by [`set_time_base`].
1548    pub async fn get_time_base(&mut self) -> Result<u32, TinkerforgeError> {
1549        let payload = [0; 0];
1550
1551        #[allow(unused_variables)]
1552        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetTimeBase), &payload).await?;
1553        Ok(u32::from_le_byte_slice(result.body()))
1554    }
1555
1556    /// Returns the following parameters: The current velocity,
1557    /// the current position, the remaining steps, the stack voltage, the external
1558    /// voltage and the current consumption of the stepper motor.
1559    ///
1560    /// The current consumption is calculated by multiplying the ``Actual Motor Current``
1561    /// value (see [`set_basic_configuration`]) with the ``Motor Run Current``
1562    /// (see [`get_driver_status`]). This is an internal calculation of the
1563    /// driver, not an independent external measurement.
1564    ///
1565    /// The current consumption calculation was broken up to firmware 2.0.1, it is fixed
1566    /// since firmware 2.0.2.
1567    ///
1568    /// There is also a receiver for this function, see [`get_all_data_callback_receiver`] receiver.
1569    pub async fn get_all_data(&mut self) -> Result<AllData, TinkerforgeError> {
1570        let payload = [0; 0];
1571
1572        #[allow(unused_variables)]
1573        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetAllData), &payload).await?;
1574        Ok(AllData::from_le_byte_slice(result.body()))
1575    }
1576
1577    /// Sets the period with which the [`get_all_data_callback_receiver`] receiver is triggered
1578    /// periodically. A value of 0 turns the receiver off.
1579    pub async fn set_all_callback_configuration(&mut self, period: u32) -> Result<(), TinkerforgeError> {
1580        let mut payload = [0; 4];
1581        period.write_to_slice(&mut payload[0..4]);
1582
1583        #[allow(unused_variables)]
1584        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetAllCallbackConfiguration), &payload).await?;
1585        Ok(())
1586    }
1587
1588    /// Returns the period as set by [`set_all_callback_configuration`].
1589    pub async fn get_all_data_callback_configuraton(&mut self) -> Result<u32, TinkerforgeError> {
1590        let payload = [0; 0];
1591
1592        #[allow(unused_variables)]
1593        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetAllDataCallbackConfiguraton), &payload).await?;
1594        Ok(u32::from_le_byte_slice(result.body()))
1595    }
1596
1597    /// Sets the GPIO configuration for the given channel.
1598    /// You can configure a debounce and the deceleration that is used if the action is
1599    /// configured as ``normal stop``. See [`set_gpio_action`].
1600    pub async fn set_gpio_configuration(&mut self, channel: u8, debounce: u16, stop_deceleration: u16) -> Result<(), TinkerforgeError> {
1601        let mut payload = [0; 5];
1602        channel.write_to_slice(&mut payload[0..1]);
1603        debounce.write_to_slice(&mut payload[1..3]);
1604        stop_deceleration.write_to_slice(&mut payload[3..5]);
1605
1606        #[allow(unused_variables)]
1607        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetGpioConfiguration), &payload).await?;
1608        Ok(())
1609    }
1610
1611    /// Returns the GPIO configuration for a channel as set by [`set_gpio_configuration`].
1612    pub async fn get_gpio_configuration(&mut self, channel: u8) -> Result<GpioConfiguration, TinkerforgeError> {
1613        let mut payload = [0; 1];
1614        channel.write_to_slice(&mut payload[0..1]);
1615
1616        #[allow(unused_variables)]
1617        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetGpioConfiguration), &payload).await?;
1618        Ok(GpioConfiguration::from_le_byte_slice(result.body()))
1619    }
1620
1621    /// Sets the GPIO action for the given channel.
1622    ///
1623    /// The action can be a normal stop, a full brake or a receiver. Each for a rising
1624    /// edge or falling edge. The actions are a bitmask they can be used at the same time.
1625    /// You can for example trigger a full brake and a receiver at the same time or for
1626    /// rising and falling edge.
1627    ///
1628    /// The deceleration speed for the normal stop can be configured with
1629    /// [`set_gpio_configuration`].
1630    ///
1631    /// Associated constants:
1632    /// * SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NONE
1633    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NORMAL_STOP_RISING_EDGE
1634    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NORMAL_STOP_FALLING_EDGE
1635    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_FULL_BRAKE_RISING_EDGE
1636    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_FULL_BRAKE_FALLING_EDGE
1637    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_CALLBACK_RISING_EDGE
1638    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_CALLBACK_FALLING_EDGE
1639    pub async fn set_gpio_action(&mut self, channel: u8, action: u32) -> Result<(), TinkerforgeError> {
1640        let mut payload = [0; 5];
1641        channel.write_to_slice(&mut payload[0..1]);
1642        action.write_to_slice(&mut payload[1..5]);
1643
1644        #[allow(unused_variables)]
1645        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetGpioAction), &payload).await?;
1646        Ok(())
1647    }
1648
1649    /// Returns the GPIO action for a channel as set by [`set_gpio_action`].
1650    ///
1651    /// Associated constants:
1652    /// * SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NONE
1653    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NORMAL_STOP_RISING_EDGE
1654    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_NORMAL_STOP_FALLING_EDGE
1655    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_FULL_BRAKE_RISING_EDGE
1656    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_FULL_BRAKE_FALLING_EDGE
1657    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_CALLBACK_RISING_EDGE
1658    ///	* SILENT_STEPPER_V2_BRICKLET_GPIO_ACTION_CALLBACK_FALLING_EDGE
1659    pub async fn get_gpio_action(&mut self, channel: u8) -> Result<u32, TinkerforgeError> {
1660        let mut payload = [0; 1];
1661        channel.write_to_slice(&mut payload[0..1]);
1662
1663        #[allow(unused_variables)]
1664        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetGpioAction), &payload).await?;
1665        Ok(u32::from_le_byte_slice(result.body()))
1666    }
1667
1668    /// Returns the GPIO state for both channels. True if the state is ``high`` and
1669    /// false if the state is ``low``.
1670    pub async fn get_gpio_state(&mut self) -> Result<Box<[bool; 2]>, TinkerforgeError> {
1671        let payload = [0; 0];
1672
1673        #[allow(unused_variables)]
1674        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetGpioState), &payload).await?;
1675        Ok(Box::<[bool; 2]>::from_le_byte_slice(result.body()))
1676    }
1677
1678    /// Returns the error count for the communication between Brick and Bricklet.
1679    ///
1680    /// The errors are divided into
1681    ///
1682    /// * ACK checksum errors,
1683    /// * message checksum errors,
1684    /// * framing errors and
1685    /// * overflow errors.
1686    ///
1687    /// The errors counts are for errors that occur on the Bricklet side. All
1688    /// Bricks have a similar function that returns the errors on the Brick side.
1689    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
1690        let payload = [0; 0];
1691
1692        #[allow(unused_variables)]
1693        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetSpitfpErrorCount), &payload).await?;
1694        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
1695    }
1696
1697    /// Sets the bootloader mode and returns the status after the requested
1698    /// mode change was instigated.
1699    ///
1700    /// You can change from bootloader mode to firmware mode and vice versa. A change
1701    /// from bootloader mode to firmware mode will only take place if the entry function,
1702    /// device identifier and CRC are present and correct.
1703    ///
1704    /// This function is used by Brick Viewer during flashing. It should not be
1705    /// necessary to call it in a normal user program.
1706    ///
1707    /// Associated constants:
1708    /// * SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1709    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1710    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1711    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1712    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1713    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_OK
1714    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
1715    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
1716    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
1717    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
1718    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
1719    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
1720        let mut payload = [0; 1];
1721        mode.write_to_slice(&mut payload[0..1]);
1722
1723        #[allow(unused_variables)]
1724        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::SetBootloaderMode), &payload).await?;
1725        Ok(u8::from_le_byte_slice(result.body()))
1726    }
1727
1728    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
1729    ///
1730    /// Associated constants:
1731    /// * SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1732    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1733    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1734    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1735    ///	* SILENT_STEPPER_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1736    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
1737        let payload = [0; 0];
1738
1739        #[allow(unused_variables)]
1740        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetBootloaderMode), &payload).await?;
1741        Ok(u8::from_le_byte_slice(result.body()))
1742    }
1743
1744    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
1745    /// to be increased by chunks of size 64. The data is written to flash
1746    /// every 4 chunks (which equals to one page of size 256).
1747    ///
1748    /// This function is used by Brick Viewer during flashing. It should not be
1749    /// necessary to call it in a normal user program.
1750    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
1751        let mut payload = [0; 4];
1752        pointer.write_to_slice(&mut payload[0..4]);
1753
1754        #[allow(unused_variables)]
1755        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetWriteFirmwarePointer), &payload).await?;
1756        Ok(())
1757    }
1758
1759    /// Writes 64 Bytes of firmware at the position as written by
1760    /// [`set_write_firmware_pointer`] before. The firmware is written
1761    /// to flash every 4 chunks.
1762    ///
1763    /// You can only write firmware in bootloader mode.
1764    ///
1765    /// This function is used by Brick Viewer during flashing. It should not be
1766    /// necessary to call it in a normal user program.
1767    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
1768        let mut payload = [0; 64];
1769        data.write_to_slice(&mut payload[0..64]);
1770
1771        #[allow(unused_variables)]
1772        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::WriteFirmware), &payload).await?;
1773        Ok(u8::from_le_byte_slice(result.body()))
1774    }
1775
1776    /// Sets the status LED configuration. By default the LED shows
1777    /// communication traffic between Brick and Bricklet, it flickers once
1778    /// for every 10 received data packets.
1779    ///
1780    /// You can also turn the LED permanently on/off or show a heartbeat.
1781    ///
1782    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
1783    ///
1784    /// Associated constants:
1785    /// * SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_OFF
1786    ///	* SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_ON
1787    ///	* SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1788    ///	* SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1789    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
1790        let mut payload = [0; 1];
1791        config.write_to_slice(&mut payload[0..1]);
1792
1793        #[allow(unused_variables)]
1794        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::SetStatusLedConfig), &payload).await?;
1795        Ok(())
1796    }
1797
1798    /// Returns the configuration as set by [`set_status_led_config`]
1799    ///
1800    /// Associated constants:
1801    /// * SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_OFF
1802    ///	* SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_ON
1803    ///	* SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1804    ///	* SILENT_STEPPER_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1805    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
1806        let payload = [0; 0];
1807
1808        #[allow(unused_variables)]
1809        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetStatusLedConfig), &payload).await?;
1810        Ok(u8::from_le_byte_slice(result.body()))
1811    }
1812
1813    /// Returns the temperature as measured inside the microcontroller. The
1814    /// value returned is not the ambient temperature!
1815    ///
1816    /// The temperature is only proportional to the real temperature and it has bad
1817    /// accuracy. Practically it is only useful as an indicator for
1818    /// temperature changes.
1819    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
1820        let payload = [0; 0];
1821
1822        #[allow(unused_variables)]
1823        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetChipTemperature), &payload).await?;
1824        Ok(i16::from_le_byte_slice(result.body()))
1825    }
1826
1827    /// Calling this function will reset the Bricklet. All configurations
1828    /// will be lost.
1829    ///
1830    /// After a reset you have to create new device objects,
1831    /// calling functions on the existing ones will result in
1832    /// undefined behavior!
1833    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
1834        let payload = [0; 0];
1835
1836        #[allow(unused_variables)]
1837        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::Reset), &payload).await?;
1838        Ok(())
1839    }
1840
1841    /// Writes a new UID into flash. If you want to set a new UID
1842    /// you have to decode the Base58 encoded UID string into an
1843    /// integer first.
1844    ///
1845    /// We recommend that you use Brick Viewer to change the UID.
1846    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
1847        let mut payload = [0; 4];
1848        uid.write_to_slice(&mut payload[0..4]);
1849
1850        #[allow(unused_variables)]
1851        let result = self.device.set(u8::from(SilentStepperV2BrickletFunction::WriteUid), &payload).await?;
1852        Ok(())
1853    }
1854
1855    /// Returns the current UID as an integer. Encode as
1856    /// Base58 to get the usual string version.
1857    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
1858        let payload = [0; 0];
1859
1860        #[allow(unused_variables)]
1861        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::ReadUid), &payload).await?;
1862        Ok(u32::from_le_byte_slice(result.body()))
1863    }
1864
1865    /// Returns the UID, the UID where the Bricklet is connected to,
1866    /// the position, the hardware and firmware version as well as the
1867    /// device identifier.
1868    ///
1869    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
1870    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
1871    /// position 'z'.
1872    ///
1873    /// The device identifier numbers can be found [here](device_identifier).
1874    /// |device_identifier_constant|
1875    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
1876        let payload = [0; 0];
1877
1878        #[allow(unused_variables)]
1879        let result = self.device.get(u8::from(SilentStepperV2BrickletFunction::GetIdentity), &payload).await?;
1880        Ok(Identity::from_le_byte_slice(result.body()))
1881    }
1882}