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