tinkerforge/bindings/
silent_stepper_brick.rs

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