tinkerforge_async/bindings/
servo_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//! Drives up to 7 RC Servos with up to 3A.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricks/Servo_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 ServoBrickFunction {
24    Enable,
25    Disable,
26    IsEnabled,
27    SetPosition,
28    GetPosition,
29    GetCurrentPosition,
30    SetVelocity,
31    GetVelocity,
32    GetCurrentVelocity,
33    SetAcceleration,
34    GetAcceleration,
35    SetOutputVoltage,
36    GetOutputVoltage,
37    SetPulseWidth,
38    GetPulseWidth,
39    SetDegree,
40    GetDegree,
41    SetPeriod,
42    GetPeriod,
43    GetServoCurrent,
44    GetOverallCurrent,
45    GetStackInputVoltage,
46    GetExternalInputVoltage,
47    SetMinimumVoltage,
48    GetMinimumVoltage,
49    EnablePositionReachedCallback,
50    DisablePositionReachedCallback,
51    IsPositionReachedCallbackEnabled,
52    EnableVelocityReachedCallback,
53    DisableVelocityReachedCallback,
54    IsVelocityReachedCallbackEnabled,
55    SetSpitfpBaudrateConfig,
56    GetSpitfpBaudrateConfig,
57    GetSendTimeoutCount,
58    SetSpitfpBaudrate,
59    GetSpitfpBaudrate,
60    GetSpitfpErrorCount,
61    EnableStatusLed,
62    DisableStatusLed,
63    IsStatusLedEnabled,
64    GetProtocol1BrickletName,
65    GetChipTemperature,
66    Reset,
67    WriteBrickletPlugin,
68    ReadBrickletPlugin,
69    GetIdentity,
70    CallbackUnderVoltage,
71    CallbackPositionReached,
72    CallbackVelocityReached,
73}
74impl From<ServoBrickFunction> for u8 {
75    fn from(fun: ServoBrickFunction) -> Self {
76        match fun {
77            ServoBrickFunction::Enable => 1,
78            ServoBrickFunction::Disable => 2,
79            ServoBrickFunction::IsEnabled => 3,
80            ServoBrickFunction::SetPosition => 4,
81            ServoBrickFunction::GetPosition => 5,
82            ServoBrickFunction::GetCurrentPosition => 6,
83            ServoBrickFunction::SetVelocity => 7,
84            ServoBrickFunction::GetVelocity => 8,
85            ServoBrickFunction::GetCurrentVelocity => 9,
86            ServoBrickFunction::SetAcceleration => 10,
87            ServoBrickFunction::GetAcceleration => 11,
88            ServoBrickFunction::SetOutputVoltage => 12,
89            ServoBrickFunction::GetOutputVoltage => 13,
90            ServoBrickFunction::SetPulseWidth => 14,
91            ServoBrickFunction::GetPulseWidth => 15,
92            ServoBrickFunction::SetDegree => 16,
93            ServoBrickFunction::GetDegree => 17,
94            ServoBrickFunction::SetPeriod => 18,
95            ServoBrickFunction::GetPeriod => 19,
96            ServoBrickFunction::GetServoCurrent => 20,
97            ServoBrickFunction::GetOverallCurrent => 21,
98            ServoBrickFunction::GetStackInputVoltage => 22,
99            ServoBrickFunction::GetExternalInputVoltage => 23,
100            ServoBrickFunction::SetMinimumVoltage => 24,
101            ServoBrickFunction::GetMinimumVoltage => 25,
102            ServoBrickFunction::EnablePositionReachedCallback => 29,
103            ServoBrickFunction::DisablePositionReachedCallback => 30,
104            ServoBrickFunction::IsPositionReachedCallbackEnabled => 31,
105            ServoBrickFunction::EnableVelocityReachedCallback => 32,
106            ServoBrickFunction::DisableVelocityReachedCallback => 33,
107            ServoBrickFunction::IsVelocityReachedCallbackEnabled => 34,
108            ServoBrickFunction::SetSpitfpBaudrateConfig => 231,
109            ServoBrickFunction::GetSpitfpBaudrateConfig => 232,
110            ServoBrickFunction::GetSendTimeoutCount => 233,
111            ServoBrickFunction::SetSpitfpBaudrate => 234,
112            ServoBrickFunction::GetSpitfpBaudrate => 235,
113            ServoBrickFunction::GetSpitfpErrorCount => 237,
114            ServoBrickFunction::EnableStatusLed => 238,
115            ServoBrickFunction::DisableStatusLed => 239,
116            ServoBrickFunction::IsStatusLedEnabled => 240,
117            ServoBrickFunction::GetProtocol1BrickletName => 241,
118            ServoBrickFunction::GetChipTemperature => 242,
119            ServoBrickFunction::Reset => 243,
120            ServoBrickFunction::WriteBrickletPlugin => 246,
121            ServoBrickFunction::ReadBrickletPlugin => 247,
122            ServoBrickFunction::GetIdentity => 255,
123            ServoBrickFunction::CallbackUnderVoltage => 26,
124            ServoBrickFunction::CallbackPositionReached => 27,
125            ServoBrickFunction::CallbackVelocityReached => 28,
126        }
127    }
128}
129pub const SERVO_BRICK_COMMUNICATION_METHOD_NONE: u8 = 0;
130pub const SERVO_BRICK_COMMUNICATION_METHOD_USB: u8 = 1;
131pub const SERVO_BRICK_COMMUNICATION_METHOD_SPI_STACK: u8 = 2;
132pub const SERVO_BRICK_COMMUNICATION_METHOD_CHIBI: u8 = 3;
133pub const SERVO_BRICK_COMMUNICATION_METHOD_RS485: u8 = 4;
134pub const SERVO_BRICK_COMMUNICATION_METHOD_WIFI: u8 = 5;
135pub const SERVO_BRICK_COMMUNICATION_METHOD_ETHERNET: u8 = 6;
136pub const SERVO_BRICK_COMMUNICATION_METHOD_WIFI_V2: u8 = 7;
137
138#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
139pub struct PulseWidth {
140    pub min: u16,
141    pub max: u16,
142}
143impl FromByteSlice for PulseWidth {
144    fn bytes_expected() -> usize {
145        4
146    }
147    fn from_le_byte_slice(bytes: &[u8]) -> PulseWidth {
148        PulseWidth { min: <u16>::from_le_byte_slice(&bytes[0..2]), max: <u16>::from_le_byte_slice(&bytes[2..4]) }
149    }
150}
151
152#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
153pub struct Degree {
154    pub min: i16,
155    pub max: i16,
156}
157impl FromByteSlice for Degree {
158    fn bytes_expected() -> usize {
159        4
160    }
161    fn from_le_byte_slice(bytes: &[u8]) -> Degree {
162        Degree { min: <i16>::from_le_byte_slice(&bytes[0..2]), max: <i16>::from_le_byte_slice(&bytes[2..4]) }
163    }
164}
165
166#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
167pub struct PositionReachedEvent {
168    pub servo_num: u8,
169    pub position: i16,
170}
171impl FromByteSlice for PositionReachedEvent {
172    fn bytes_expected() -> usize {
173        3
174    }
175    fn from_le_byte_slice(bytes: &[u8]) -> PositionReachedEvent {
176        PositionReachedEvent { servo_num: <u8>::from_le_byte_slice(&bytes[0..1]), position: <i16>::from_le_byte_slice(&bytes[1..3]) }
177    }
178}
179
180#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
181pub struct VelocityReachedEvent {
182    pub servo_num: u8,
183    pub velocity: i16,
184}
185impl FromByteSlice for VelocityReachedEvent {
186    fn bytes_expected() -> usize {
187        3
188    }
189    fn from_le_byte_slice(bytes: &[u8]) -> VelocityReachedEvent {
190        VelocityReachedEvent { servo_num: <u8>::from_le_byte_slice(&bytes[0..1]), velocity: <i16>::from_le_byte_slice(&bytes[1..3]) }
191    }
192}
193
194#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
195pub struct SpitfpBaudrateConfig {
196    pub enable_dynamic_baudrate: bool,
197    pub minimum_dynamic_baudrate: u32,
198}
199impl FromByteSlice for SpitfpBaudrateConfig {
200    fn bytes_expected() -> usize {
201        5
202    }
203    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpBaudrateConfig {
204        SpitfpBaudrateConfig {
205            enable_dynamic_baudrate: <bool>::from_le_byte_slice(&bytes[0..1]),
206            minimum_dynamic_baudrate: <u32>::from_le_byte_slice(&bytes[1..5]),
207        }
208    }
209}
210
211#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
212pub struct SpitfpErrorCount {
213    pub error_count_ack_checksum: u32,
214    pub error_count_message_checksum: u32,
215    pub error_count_frame: u32,
216    pub error_count_overflow: u32,
217}
218impl FromByteSlice for SpitfpErrorCount {
219    fn bytes_expected() -> usize {
220        16
221    }
222    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
223        SpitfpErrorCount {
224            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
225            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
226            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
227            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
228        }
229    }
230}
231
232#[derive(Clone)]
233pub struct Protocol1BrickletName {
234    pub protocol_version: u8,
235    pub firmware_version: [u8; 3],
236    pub name: String,
237}
238impl FromByteSlice for Protocol1BrickletName {
239    fn bytes_expected() -> usize {
240        44
241    }
242    fn from_le_byte_slice(bytes: &[u8]) -> Protocol1BrickletName {
243        Protocol1BrickletName {
244            protocol_version: <u8>::from_le_byte_slice(&bytes[0..1]),
245            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[1..4]),
246            name: <String>::from_le_byte_slice(&bytes[4..44]),
247        }
248    }
249}
250
251#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
252pub struct Identity {
253    pub uid: String,
254    pub connected_uid: String,
255    pub position: char,
256    pub hardware_version: [u8; 3],
257    pub firmware_version: [u8; 3],
258    pub device_identifier: u16,
259}
260impl FromByteSlice for Identity {
261    fn bytes_expected() -> usize {
262        25
263    }
264    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
265        Identity {
266            uid: <String>::from_le_byte_slice(&bytes[0..8]),
267            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
268            position: <char>::from_le_byte_slice(&bytes[16..17]),
269            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
270            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
271            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
272        }
273    }
274}
275
276/// Drives up to 7 RC Servos with up to 3A
277#[derive(Clone)]
278pub struct ServoBrick {
279    device: Device,
280}
281impl ServoBrick {
282    pub const DEVICE_IDENTIFIER: u16 = 14;
283    pub const DEVICE_DISPLAY_NAME: &'static str = "Servo Brick";
284    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
285    pub fn new(uid: Uid, connection: AsyncIpConnection) -> ServoBrick {
286        let mut result = ServoBrick { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
287        result.device.response_expected[u8::from(ServoBrickFunction::Enable) as usize] = ResponseExpectedFlag::False;
288        result.device.response_expected[u8::from(ServoBrickFunction::Disable) as usize] = ResponseExpectedFlag::False;
289        result.device.response_expected[u8::from(ServoBrickFunction::IsEnabled) as usize] = ResponseExpectedFlag::AlwaysTrue;
290        result.device.response_expected[u8::from(ServoBrickFunction::SetPosition) as usize] = ResponseExpectedFlag::False;
291        result.device.response_expected[u8::from(ServoBrickFunction::GetPosition) as usize] = ResponseExpectedFlag::AlwaysTrue;
292        result.device.response_expected[u8::from(ServoBrickFunction::GetCurrentPosition) as usize] = ResponseExpectedFlag::AlwaysTrue;
293        result.device.response_expected[u8::from(ServoBrickFunction::SetVelocity) as usize] = ResponseExpectedFlag::False;
294        result.device.response_expected[u8::from(ServoBrickFunction::GetVelocity) as usize] = ResponseExpectedFlag::AlwaysTrue;
295        result.device.response_expected[u8::from(ServoBrickFunction::GetCurrentVelocity) as usize] = ResponseExpectedFlag::AlwaysTrue;
296        result.device.response_expected[u8::from(ServoBrickFunction::SetAcceleration) as usize] = ResponseExpectedFlag::False;
297        result.device.response_expected[u8::from(ServoBrickFunction::GetAcceleration) as usize] = ResponseExpectedFlag::AlwaysTrue;
298        result.device.response_expected[u8::from(ServoBrickFunction::SetOutputVoltage) as usize] = ResponseExpectedFlag::False;
299        result.device.response_expected[u8::from(ServoBrickFunction::GetOutputVoltage) as usize] = ResponseExpectedFlag::AlwaysTrue;
300        result.device.response_expected[u8::from(ServoBrickFunction::SetPulseWidth) as usize] = ResponseExpectedFlag::False;
301        result.device.response_expected[u8::from(ServoBrickFunction::GetPulseWidth) as usize] = ResponseExpectedFlag::AlwaysTrue;
302        result.device.response_expected[u8::from(ServoBrickFunction::SetDegree) as usize] = ResponseExpectedFlag::False;
303        result.device.response_expected[u8::from(ServoBrickFunction::GetDegree) as usize] = ResponseExpectedFlag::AlwaysTrue;
304        result.device.response_expected[u8::from(ServoBrickFunction::SetPeriod) as usize] = ResponseExpectedFlag::False;
305        result.device.response_expected[u8::from(ServoBrickFunction::GetPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
306        result.device.response_expected[u8::from(ServoBrickFunction::GetServoCurrent) as usize] = ResponseExpectedFlag::AlwaysTrue;
307        result.device.response_expected[u8::from(ServoBrickFunction::GetOverallCurrent) as usize] = ResponseExpectedFlag::AlwaysTrue;
308        result.device.response_expected[u8::from(ServoBrickFunction::GetStackInputVoltage) as usize] = ResponseExpectedFlag::AlwaysTrue;
309        result.device.response_expected[u8::from(ServoBrickFunction::GetExternalInputVoltage) as usize] = ResponseExpectedFlag::AlwaysTrue;
310        result.device.response_expected[u8::from(ServoBrickFunction::SetMinimumVoltage) as usize] = ResponseExpectedFlag::True;
311        result.device.response_expected[u8::from(ServoBrickFunction::GetMinimumVoltage) as usize] = ResponseExpectedFlag::AlwaysTrue;
312        result.device.response_expected[u8::from(ServoBrickFunction::EnablePositionReachedCallback) as usize] = ResponseExpectedFlag::True;
313        result.device.response_expected[u8::from(ServoBrickFunction::DisablePositionReachedCallback) as usize] = ResponseExpectedFlag::True;
314        result.device.response_expected[u8::from(ServoBrickFunction::IsPositionReachedCallbackEnabled) as usize] =
315            ResponseExpectedFlag::AlwaysTrue;
316        result.device.response_expected[u8::from(ServoBrickFunction::EnableVelocityReachedCallback) as usize] = ResponseExpectedFlag::True;
317        result.device.response_expected[u8::from(ServoBrickFunction::DisableVelocityReachedCallback) as usize] = ResponseExpectedFlag::True;
318        result.device.response_expected[u8::from(ServoBrickFunction::IsVelocityReachedCallbackEnabled) as usize] =
319            ResponseExpectedFlag::AlwaysTrue;
320        result.device.response_expected[u8::from(ServoBrickFunction::SetSpitfpBaudrateConfig) as usize] = ResponseExpectedFlag::False;
321        result.device.response_expected[u8::from(ServoBrickFunction::GetSpitfpBaudrateConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
322        result.device.response_expected[u8::from(ServoBrickFunction::GetSendTimeoutCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
323        result.device.response_expected[u8::from(ServoBrickFunction::SetSpitfpBaudrate) as usize] = ResponseExpectedFlag::False;
324        result.device.response_expected[u8::from(ServoBrickFunction::GetSpitfpBaudrate) as usize] = ResponseExpectedFlag::AlwaysTrue;
325        result.device.response_expected[u8::from(ServoBrickFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
326        result.device.response_expected[u8::from(ServoBrickFunction::EnableStatusLed) as usize] = ResponseExpectedFlag::False;
327        result.device.response_expected[u8::from(ServoBrickFunction::DisableStatusLed) as usize] = ResponseExpectedFlag::False;
328        result.device.response_expected[u8::from(ServoBrickFunction::IsStatusLedEnabled) as usize] = ResponseExpectedFlag::AlwaysTrue;
329        result.device.response_expected[u8::from(ServoBrickFunction::GetProtocol1BrickletName) as usize] = ResponseExpectedFlag::AlwaysTrue;
330        result.device.response_expected[u8::from(ServoBrickFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
331        result.device.response_expected[u8::from(ServoBrickFunction::Reset) as usize] = ResponseExpectedFlag::False;
332        result.device.response_expected[u8::from(ServoBrickFunction::WriteBrickletPlugin) as usize] = ResponseExpectedFlag::False;
333        result.device.response_expected[u8::from(ServoBrickFunction::ReadBrickletPlugin) as usize] = ResponseExpectedFlag::AlwaysTrue;
334        result.device.response_expected[u8::from(ServoBrickFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
335        result
336    }
337
338    /// Returns the response expected flag for the function specified by the function ID parameter.
339    /// It is true if the function is expected to send a response, false otherwise.
340    ///
341    /// For getter functions this is enabled by default and cannot be disabled, because those
342    /// functions will always send a response. For callback configuration functions it is enabled
343    /// by default too, but can be disabled by [`set_response_expected`](crate::servo_brick::ServoBrick::set_response_expected).
344    /// For setter functions it is disabled by default and can be enabled.
345    ///
346    /// Enabling the response expected flag for a setter function allows to detect timeouts
347    /// and other error conditions calls of this setter as well. The device will then send a response
348    /// for this purpose. If this flag is disabled for a setter function then no response is sent
349    /// and errors are silently ignored, because they cannot be detected.
350    ///
351    /// See [`set_response_expected`](crate::servo_brick::ServoBrick::set_response_expected) for the list of function ID constants available for this function.
352    pub fn get_response_expected(&mut self, fun: ServoBrickFunction) -> Result<bool, GetResponseExpectedError> {
353        self.device.get_response_expected(u8::from(fun))
354    }
355
356    /// Changes the response expected flag of the function specified by the function ID parameter.
357    /// This flag can only be changed for setter (default value: false) and callback configuration
358    /// functions (default value: true). For getter functions it is always enabled.
359    ///
360    /// Enabling the response expected flag for a setter function allows to detect timeouts and
361    /// other error conditions calls of this setter as well. The device will then send a response
362    /// for this purpose. If this flag is disabled for a setter function then no response is sent
363    /// and errors are silently ignored, because they cannot be detected.
364    pub fn set_response_expected(&mut self, fun: ServoBrickFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
365        self.device.set_response_expected(u8::from(fun), response_expected)
366    }
367
368    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
369    pub fn set_response_expected_all(&mut self, response_expected: bool) {
370        self.device.set_response_expected_all(response_expected)
371    }
372
373    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
374    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
375    pub fn get_api_version(&self) -> [u8; 3] {
376        self.device.api_version
377    }
378
379    /// This receiver is triggered when the input voltage drops below the value set by
380    /// [`set_minimum_voltage`]. The parameter is the current voltage.
381    ///
382    /// [`set_minimum_voltage`]: #method.set_minimum_voltage
383    pub async fn get_under_voltage_callback_receiver(&mut self) -> impl Stream<Item = u16> {
384        self.device
385            .get_callback_receiver(u8::from(ServoBrickFunction::CallbackUnderVoltage))
386            .await
387            .map(|p| u16::from_le_byte_slice(p.body()))
388    }
389
390    /// This receiver is triggered when a position set by [`set_position`]
391    /// is reached. If the new position matches the current position then the
392    /// receiver is not triggered, because the servo didn't move.
393    /// The parameters are the servo and the position that is reached.
394    ///
395    /// You can enable this receiver with [`enable_position_reached_callback`].
396    ///
397    /// # Note
398    ///  Since we can't get any feedback from the servo, this only works if the
399    ///  velocity (see [`set_velocity`]) is set smaller or equal to the
400    ///  maximum velocity of the servo. Otherwise the servo will lag behind the
401    ///  control value and the receiver will be triggered too early.
402    pub async fn get_position_reached_callback_receiver(&mut self) -> impl Stream<Item = PositionReachedEvent> {
403        self.device
404            .get_callback_receiver(u8::from(ServoBrickFunction::CallbackPositionReached))
405            .await
406            .map(|p| PositionReachedEvent::from_le_byte_slice(p.body()))
407    }
408
409    /// This receiver is triggered when a velocity set by [`set_velocity`]
410    /// is reached. The parameters are the servo and the velocity that is reached.
411    ///
412    /// You can enable this receiver with [`enable_velocity_reached_callback`].
413    ///
414    /// # Note
415    ///  Since we can't get any feedback from the servo, this only works if the
416    ///  acceleration (see [`set_acceleration`]) is set smaller or equal to the
417    ///  maximum acceleration of the servo. Otherwise the servo will lag behind the
418    ///  control value and the receiver will be triggered too early.
419    pub async fn get_velocity_reached_callback_receiver(&mut self) -> impl Stream<Item = VelocityReachedEvent> {
420        self.device
421            .get_callback_receiver(u8::from(ServoBrickFunction::CallbackVelocityReached))
422            .await
423            .map(|p| VelocityReachedEvent::from_le_byte_slice(p.body()))
424    }
425
426    /// Enables a servo (0 to 6). If a servo is enabled, the configured position,
427    /// velocity, acceleration, etc. are applied immediately.
428    pub async fn enable(&mut self, servo_num: u8) -> Result<(), TinkerforgeError> {
429        let mut payload = [0; 1];
430        servo_num.write_to_slice(&mut payload[0..1]);
431
432        #[allow(unused_variables)]
433        let result = self.device.set(u8::from(ServoBrickFunction::Enable), &payload).await?;
434        Ok(())
435    }
436
437    /// Disables a servo (0 to 6). Disabled servos are not driven at all, i.e. a
438    /// disabled servo will not hold its position if a load is applied.
439    pub async fn disable(&mut self, servo_num: u8) -> Result<(), TinkerforgeError> {
440        let mut payload = [0; 1];
441        servo_num.write_to_slice(&mut payload[0..1]);
442
443        #[allow(unused_variables)]
444        let result = self.device.set(u8::from(ServoBrickFunction::Disable), &payload).await?;
445        Ok(())
446    }
447
448    /// Returns *true* if the specified servo is enabled, *false* otherwise.
449    pub async fn is_enabled(&mut self, servo_num: u8) -> Result<bool, TinkerforgeError> {
450        let mut payload = [0; 1];
451        servo_num.write_to_slice(&mut payload[0..1]);
452
453        #[allow(unused_variables)]
454        let result = self.device.get(u8::from(ServoBrickFunction::IsEnabled), &payload).await?;
455        Ok(bool::from_le_byte_slice(result.body()))
456    }
457
458    /// Sets the position for the specified servo.
459    ///
460    /// The default range of the position is -9000 to 9000, but it can be specified
461    /// according to your servo with [`set_degree`].
462    ///
463    /// If you want to control a linear servo or RC brushless motor controller or
464    /// similar with the Servo Brick, you can also define lengths or speeds with
465    /// [`set_degree`].
466    pub async fn set_position(&mut self, servo_num: u8, position: i16) -> Result<(), TinkerforgeError> {
467        let mut payload = [0; 3];
468        servo_num.write_to_slice(&mut payload[0..1]);
469        position.write_to_slice(&mut payload[1..3]);
470
471        #[allow(unused_variables)]
472        let result = self.device.set(u8::from(ServoBrickFunction::SetPosition), &payload).await?;
473        Ok(())
474    }
475
476    /// Returns the position of the specified servo as set by [`set_position`].
477    pub async fn get_position(&mut self, servo_num: u8) -> Result<i16, TinkerforgeError> {
478        let mut payload = [0; 1];
479        servo_num.write_to_slice(&mut payload[0..1]);
480
481        #[allow(unused_variables)]
482        let result = self.device.get(u8::from(ServoBrickFunction::GetPosition), &payload).await?;
483        Ok(i16::from_le_byte_slice(result.body()))
484    }
485
486    /// Returns the *current* position of the specified servo. This may not be the
487    /// value of [`set_position`] if the servo is currently approaching a
488    /// position goal.
489    pub async fn get_current_position(&mut self, servo_num: u8) -> Result<i16, TinkerforgeError> {
490        let mut payload = [0; 1];
491        servo_num.write_to_slice(&mut payload[0..1]);
492
493        #[allow(unused_variables)]
494        let result = self.device.get(u8::from(ServoBrickFunction::GetCurrentPosition), &payload).await?;
495        Ok(i16::from_le_byte_slice(result.body()))
496    }
497
498    /// Sets the maximum velocity of the specified servo. The velocity
499    /// is accelerated according to the value set by [`set_acceleration`].
500    ///
501    /// The minimum velocity is 0 (no movement) and the maximum velocity is 65535.
502    /// With a value of 65535 the position will be set immediately (no velocity).
503    pub async fn set_velocity(&mut self, servo_num: u8, velocity: u16) -> Result<(), TinkerforgeError> {
504        let mut payload = [0; 3];
505        servo_num.write_to_slice(&mut payload[0..1]);
506        velocity.write_to_slice(&mut payload[1..3]);
507
508        #[allow(unused_variables)]
509        let result = self.device.set(u8::from(ServoBrickFunction::SetVelocity), &payload).await?;
510        Ok(())
511    }
512
513    /// Returns the velocity of the specified servo as set by [`set_velocity`].
514    pub async fn get_velocity(&mut self, servo_num: u8) -> Result<u16, TinkerforgeError> {
515        let mut payload = [0; 1];
516        servo_num.write_to_slice(&mut payload[0..1]);
517
518        #[allow(unused_variables)]
519        let result = self.device.get(u8::from(ServoBrickFunction::GetVelocity), &payload).await?;
520        Ok(u16::from_le_byte_slice(result.body()))
521    }
522
523    /// Returns the *current* velocity of the specified servo. This may not be the
524    /// value of [`set_velocity`] if the servo is currently approaching a
525    /// velocity goal.
526    pub async fn get_current_velocity(&mut self, servo_num: u8) -> Result<u16, TinkerforgeError> {
527        let mut payload = [0; 1];
528        servo_num.write_to_slice(&mut payload[0..1]);
529
530        #[allow(unused_variables)]
531        let result = self.device.get(u8::from(ServoBrickFunction::GetCurrentVelocity), &payload).await?;
532        Ok(u16::from_le_byte_slice(result.body()))
533    }
534
535    /// Sets the acceleration of the specified servo.
536    ///
537    /// The minimum acceleration is 1 and the maximum acceleration is 65535.
538    /// With a value of 65535 the velocity will be set immediately (no acceleration).
539    pub async fn set_acceleration(&mut self, servo_num: u8, acceleration: u16) -> Result<(), TinkerforgeError> {
540        let mut payload = [0; 3];
541        servo_num.write_to_slice(&mut payload[0..1]);
542        acceleration.write_to_slice(&mut payload[1..3]);
543
544        #[allow(unused_variables)]
545        let result = self.device.set(u8::from(ServoBrickFunction::SetAcceleration), &payload).await?;
546        Ok(())
547    }
548
549    /// Returns the acceleration for the specified servo as set by
550    /// [`set_acceleration`].
551    pub async fn get_acceleration(&mut self, servo_num: u8) -> Result<u16, TinkerforgeError> {
552        let mut payload = [0; 1];
553        servo_num.write_to_slice(&mut payload[0..1]);
554
555        #[allow(unused_variables)]
556        let result = self.device.get(u8::from(ServoBrickFunction::GetAcceleration), &payload).await?;
557        Ok(u16::from_le_byte_slice(result.body()))
558    }
559
560    /// Sets the output voltages with which the servos are driven.
561    ///
562    /// # Note
563    ///  We recommend that you set this value to the maximum voltage that is
564    ///  specified for your servo, most servos achieve their maximum force only
565    ///  with high voltages.
566    pub async fn set_output_voltage(&mut self, voltage: u16) -> Result<(), TinkerforgeError> {
567        let mut payload = [0; 2];
568        voltage.write_to_slice(&mut payload[0..2]);
569
570        #[allow(unused_variables)]
571        let result = self.device.set(u8::from(ServoBrickFunction::SetOutputVoltage), &payload).await?;
572        Ok(())
573    }
574
575    /// Returns the output voltage as specified by [`set_output_voltage`].
576    pub async fn get_output_voltage(&mut self) -> Result<u16, TinkerforgeError> {
577        let payload = [0; 0];
578
579        #[allow(unused_variables)]
580        let result = self.device.get(u8::from(ServoBrickFunction::GetOutputVoltage), &payload).await?;
581        Ok(u16::from_le_byte_slice(result.body()))
582    }
583
584    /// Sets the minimum and maximum pulse width of the specified servo.
585    ///
586    /// Usually, servos are controlled with a
587    /// [PWM](https://en.wikipedia.org/wiki/Pulse-width_modulation)__, whereby the
588    /// length of the pulse controls the position of the servo. Every servo has
589    /// different minimum and maximum pulse widths, these can be specified with
590    /// this function.
591    ///
592    /// If you have a datasheet for your servo that specifies the minimum and
593    /// maximum pulse width, you should set the values accordingly. If your servo
594    /// comes without any datasheet you have to find the values via trial and error.
595    ///
596    /// The minimum must be smaller than the maximum.
597    pub async fn set_pulse_width(&mut self, servo_num: u8, min: u16, max: u16) -> Result<(), TinkerforgeError> {
598        let mut payload = [0; 5];
599        servo_num.write_to_slice(&mut payload[0..1]);
600        min.write_to_slice(&mut payload[1..3]);
601        max.write_to_slice(&mut payload[3..5]);
602
603        #[allow(unused_variables)]
604        let result = self.device.set(u8::from(ServoBrickFunction::SetPulseWidth), &payload).await?;
605        Ok(())
606    }
607
608    /// Returns the minimum and maximum pulse width for the specified servo as set by
609    /// [`set_pulse_width`].
610    pub async fn get_pulse_width(&mut self, servo_num: u8) -> Result<PulseWidth, TinkerforgeError> {
611        let mut payload = [0; 1];
612        servo_num.write_to_slice(&mut payload[0..1]);
613
614        #[allow(unused_variables)]
615        let result = self.device.get(u8::from(ServoBrickFunction::GetPulseWidth), &payload).await?;
616        Ok(PulseWidth::from_le_byte_slice(result.body()))
617    }
618
619    /// Sets the minimum and maximum degree for the specified servo (by default
620    /// given as °/100).
621    ///
622    /// This only specifies the abstract values between which the minimum and maximum
623    /// pulse width is scaled. For example: If you specify a pulse width of 1000µs
624    /// to 2000µs and a degree range of -90° to 90°, a call of [`set_position`]
625    /// with 0 will result in a pulse width of 1500µs
626    /// (-90° = 1000µs, 90° = 2000µs, etc.).
627    ///
628    /// Possible usage:
629    ///
630    /// * The datasheet of your servo specifies a range of 200° with the middle position
631    ///   at 110°. In this case you can set the minimum to -9000 and the maximum to 11000.
632    /// * You measure a range of 220° on your servo and you don't have or need a middle
633    ///   position. In this case you can set the minimum to 0 and the maximum to 22000.
634    /// * You have a linear servo with a drive length of 20cm, In this case you could
635    ///   set the minimum to 0 and the maximum to 20000. Now you can set the Position
636    ///   with [`set_position`] with a resolution of cm/100. Also the velocity will
637    ///   have a resolution of cm/100s and the acceleration will have a resolution of
638    ///   cm/100s².
639    /// * You don't care about units and just want the highest possible resolution. In
640    ///   this case you should set the minimum to -32767 and the maximum to 32767.
641    /// * You have a brushless motor with a maximum speed of 10000 rpm and want to
642    ///   control it with a RC brushless motor controller. In this case you can set the
643    ///   minimum to 0 and the maximum to 10000. [`set_position`] now controls the rpm.
644    ///
645    /// The minimum must be smaller than the maximum.
646    pub async fn set_degree(&mut self, servo_num: u8, min: i16, max: i16) -> Result<(), TinkerforgeError> {
647        let mut payload = [0; 5];
648        servo_num.write_to_slice(&mut payload[0..1]);
649        min.write_to_slice(&mut payload[1..3]);
650        max.write_to_slice(&mut payload[3..5]);
651
652        #[allow(unused_variables)]
653        let result = self.device.set(u8::from(ServoBrickFunction::SetDegree), &payload).await?;
654        Ok(())
655    }
656
657    /// Returns the minimum and maximum degree for the specified servo as set by
658    /// [`set_degree`].
659    pub async fn get_degree(&mut self, servo_num: u8) -> Result<Degree, TinkerforgeError> {
660        let mut payload = [0; 1];
661        servo_num.write_to_slice(&mut payload[0..1]);
662
663        #[allow(unused_variables)]
664        let result = self.device.get(u8::from(ServoBrickFunction::GetDegree), &payload).await?;
665        Ok(Degree::from_le_byte_slice(result.body()))
666    }
667
668    /// Sets the period of the specified servo.
669    ///
670    /// Usually, servos are controlled with a
671    /// [PWM](https://en.wikipedia.org/wiki/Pulse-width_modulation)__. Different
672    /// servos expect PWMs with different periods. Most servos run well with a
673    /// period of about 20ms.
674    ///
675    /// If your servo comes with a datasheet that specifies a period, you should
676    /// set it accordingly. If you don't have a datasheet and you have no idea
677    /// what the correct period is, the default value will most likely
678    /// work fine.
679    pub async fn set_period(&mut self, servo_num: u8, period: u16) -> Result<(), TinkerforgeError> {
680        let mut payload = [0; 3];
681        servo_num.write_to_slice(&mut payload[0..1]);
682        period.write_to_slice(&mut payload[1..3]);
683
684        #[allow(unused_variables)]
685        let result = self.device.set(u8::from(ServoBrickFunction::SetPeriod), &payload).await?;
686        Ok(())
687    }
688
689    /// Returns the period for the specified servo as set by [`set_period`].
690    pub async fn get_period(&mut self, servo_num: u8) -> Result<u16, TinkerforgeError> {
691        let mut payload = [0; 1];
692        servo_num.write_to_slice(&mut payload[0..1]);
693
694        #[allow(unused_variables)]
695        let result = self.device.get(u8::from(ServoBrickFunction::GetPeriod), &payload).await?;
696        Ok(u16::from_le_byte_slice(result.body()))
697    }
698
699    /// Returns the current consumption of the specified servo.
700    pub async fn get_servo_current(&mut self, servo_num: u8) -> Result<u16, TinkerforgeError> {
701        let mut payload = [0; 1];
702        servo_num.write_to_slice(&mut payload[0..1]);
703
704        #[allow(unused_variables)]
705        let result = self.device.get(u8::from(ServoBrickFunction::GetServoCurrent), &payload).await?;
706        Ok(u16::from_le_byte_slice(result.body()))
707    }
708
709    /// Returns the current consumption of all servos together.
710    pub async fn get_overall_current(&mut self) -> Result<u16, TinkerforgeError> {
711        let payload = [0; 0];
712
713        #[allow(unused_variables)]
714        let result = self.device.get(u8::from(ServoBrickFunction::GetOverallCurrent), &payload).await?;
715        Ok(u16::from_le_byte_slice(result.body()))
716    }
717
718    /// Returns the stack input voltage. The stack input voltage is the
719    /// voltage that is supplied via the stack, i.e. it is given by a
720    /// Step-Down or Step-Up Power Supply.
721    pub async fn get_stack_input_voltage(&mut self) -> Result<u16, TinkerforgeError> {
722        let payload = [0; 0];
723
724        #[allow(unused_variables)]
725        let result = self.device.get(u8::from(ServoBrickFunction::GetStackInputVoltage), &payload).await?;
726        Ok(u16::from_le_byte_slice(result.body()))
727    }
728
729    /// Returns the external input voltage. The external input voltage is
730    /// given via the black power input connector on the Servo Brick.
731    ///
732    /// If there is an external input voltage and a stack input voltage, the motors
733    /// will be driven by the external input voltage. If there is only a stack
734    /// voltage present, the motors will be driven by this voltage.
735    ///
736    /// # Warning
737    ///  This means, if you have a high stack voltage and a low external voltage,
738    ///  the motors will be driven with the low external voltage. If you then remove
739    ///  the external connection, it will immediately be driven by the high
740    ///  stack voltage
741    pub async fn get_external_input_voltage(&mut self) -> Result<u16, TinkerforgeError> {
742        let payload = [0; 0];
743
744        #[allow(unused_variables)]
745        let result = self.device.get(u8::from(ServoBrickFunction::GetExternalInputVoltage), &payload).await?;
746        Ok(u16::from_le_byte_slice(result.body()))
747    }
748
749    /// Sets the minimum voltage, below which the [`get_under_voltage_callback_receiver`] receiver
750    /// is triggered. The minimum possible value that works with the Servo Brick is 5V.
751    /// You can use this function to detect the discharge of a battery that is used
752    /// to drive the stepper motor. If you have a fixed power supply, you likely do
753    /// not need this functionality.
754    pub async fn set_minimum_voltage(&mut self, voltage: u16) -> Result<(), TinkerforgeError> {
755        let mut payload = [0; 2];
756        voltage.write_to_slice(&mut payload[0..2]);
757
758        #[allow(unused_variables)]
759        let result = self.device.set(u8::from(ServoBrickFunction::SetMinimumVoltage), &payload).await?;
760        Ok(())
761    }
762
763    /// Returns the minimum voltage as set by [`set_minimum_voltage`]
764    pub async fn get_minimum_voltage(&mut self) -> Result<u16, TinkerforgeError> {
765        let payload = [0; 0];
766
767        #[allow(unused_variables)]
768        let result = self.device.get(u8::from(ServoBrickFunction::GetMinimumVoltage), &payload).await?;
769        Ok(u16::from_le_byte_slice(result.body()))
770    }
771
772    /// Enables the [`get_position_reached_callback_receiver`] receiver.
773    ///
774    /// Default is disabled.
775    ///
776    ///
777    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
778    pub async fn enable_position_reached_callback(&mut self) -> Result<(), TinkerforgeError> {
779        let payload = [0; 0];
780
781        #[allow(unused_variables)]
782        let result = self.device.set(u8::from(ServoBrickFunction::EnablePositionReachedCallback), &payload).await?;
783        Ok(())
784    }
785
786    /// Disables the [`get_position_reached_callback_receiver`] receiver.
787    ///
788    ///
789    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
790    pub async fn disable_position_reached_callback(&mut self) -> Result<(), TinkerforgeError> {
791        let payload = [0; 0];
792
793        #[allow(unused_variables)]
794        let result = self.device.set(u8::from(ServoBrickFunction::DisablePositionReachedCallback), &payload).await?;
795        Ok(())
796    }
797
798    /// Returns *true* if [`get_position_reached_callback_receiver`] receiver is enabled, *false* otherwise.
799    ///
800    ///
801    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
802    pub async fn is_position_reached_callback_enabled(&mut self) -> Result<bool, TinkerforgeError> {
803        let payload = [0; 0];
804
805        #[allow(unused_variables)]
806        let result = self.device.get(u8::from(ServoBrickFunction::IsPositionReachedCallbackEnabled), &payload).await?;
807        Ok(bool::from_le_byte_slice(result.body()))
808    }
809
810    /// Enables the [`get_velocity_reached_callback_receiver`] receiver.
811    ///
812    /// Default is disabled.
813    ///
814    ///
815    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
816    pub async fn enable_velocity_reached_callback(&mut self) -> Result<(), TinkerforgeError> {
817        let payload = [0; 0];
818
819        #[allow(unused_variables)]
820        let result = self.device.set(u8::from(ServoBrickFunction::EnableVelocityReachedCallback), &payload).await?;
821        Ok(())
822    }
823
824    /// Disables the [`get_velocity_reached_callback_receiver`] receiver.
825    ///
826    /// Default is disabled.
827    ///
828    ///
829    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
830    pub async fn disable_velocity_reached_callback(&mut self) -> Result<(), TinkerforgeError> {
831        let payload = [0; 0];
832
833        #[allow(unused_variables)]
834        let result = self.device.set(u8::from(ServoBrickFunction::DisableVelocityReachedCallback), &payload).await?;
835        Ok(())
836    }
837
838    /// Returns *true* if [`get_velocity_reached_callback_receiver`] receiver is enabled, *false* otherwise.
839    ///
840    ///
841    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
842    pub async fn is_velocity_reached_callback_enabled(&mut self) -> Result<bool, TinkerforgeError> {
843        let payload = [0; 0];
844
845        #[allow(unused_variables)]
846        let result = self.device.get(u8::from(ServoBrickFunction::IsVelocityReachedCallbackEnabled), &payload).await?;
847        Ok(bool::from_le_byte_slice(result.body()))
848    }
849
850    /// The SPITF protocol can be used with a dynamic baudrate. If the dynamic baudrate is
851    /// enabled, the Brick will try to adapt the baudrate for the communication
852    /// between Bricks and Bricklets according to the amount of data that is transferred.
853    ///
854    /// The baudrate will be increased exponentially if lots of data is sent/received and
855    /// decreased linearly if little data is sent/received.
856    ///
857    /// This lowers the baudrate in applications where little data is transferred (e.g.
858    /// a weather station) and increases the robustness. If there is lots of data to transfer
859    /// (e.g. Thermal Imaging Bricklet) it automatically increases the baudrate as needed.
860    ///
861    /// In cases where some data has to transferred as fast as possible every few seconds
862    /// (e.g. RS485 Bricklet with a high baudrate but small payload) you may want to turn
863    /// the dynamic baudrate off to get the highest possible performance.
864    ///
865    /// The maximum value of the baudrate can be set per port with the function
866    /// [`set_spitfp_baudrate`]. If the dynamic baudrate is disabled, the baudrate
867    /// as set by [`set_spitfp_baudrate`] will be used statically.
868    ///
869    ///
870    /// .. versionadded:: 2.3.4$nbsp;(Firmware)
871    pub async fn set_spitfp_baudrate_config(
872        &mut self,
873        enable_dynamic_baudrate: bool,
874        minimum_dynamic_baudrate: u32,
875    ) -> Result<(), TinkerforgeError> {
876        let mut payload = [0; 5];
877        enable_dynamic_baudrate.write_to_slice(&mut payload[0..1]);
878        minimum_dynamic_baudrate.write_to_slice(&mut payload[1..5]);
879
880        #[allow(unused_variables)]
881        let result = self.device.set(u8::from(ServoBrickFunction::SetSpitfpBaudrateConfig), &payload).await?;
882        Ok(())
883    }
884
885    /// Returns the baudrate config, see [`set_spitfp_baudrate_config`].
886    ///
887    ///
888    /// .. versionadded:: 2.3.4$nbsp;(Firmware)
889    pub async fn get_spitfp_baudrate_config(&mut self) -> Result<SpitfpBaudrateConfig, TinkerforgeError> {
890        let payload = [0; 0];
891
892        #[allow(unused_variables)]
893        let result = self.device.get(u8::from(ServoBrickFunction::GetSpitfpBaudrateConfig), &payload).await?;
894        Ok(SpitfpBaudrateConfig::from_le_byte_slice(result.body()))
895    }
896
897    /// Returns the timeout count for the different communication methods.
898    ///
899    /// The methods 0-2 are available for all Bricks, 3-7 only for Master Bricks.
900    ///
901    /// This function is mostly used for debugging during development, in normal operation
902    /// the counters should nearly always stay at 0.
903    ///
904    ///
905    /// .. versionadded:: 2.3.2$nbsp;(Firmware)
906    ///
907    /// Associated constants:
908    /// * SERVO_BRICK_COMMUNICATION_METHOD_NONE
909    ///	* SERVO_BRICK_COMMUNICATION_METHOD_USB
910    ///	* SERVO_BRICK_COMMUNICATION_METHOD_SPI_STACK
911    ///	* SERVO_BRICK_COMMUNICATION_METHOD_CHIBI
912    ///	* SERVO_BRICK_COMMUNICATION_METHOD_RS485
913    ///	* SERVO_BRICK_COMMUNICATION_METHOD_WIFI
914    ///	* SERVO_BRICK_COMMUNICATION_METHOD_ETHERNET
915    ///	* SERVO_BRICK_COMMUNICATION_METHOD_WIFI_V2
916    pub async fn get_send_timeout_count(&mut self, communication_method: u8) -> Result<u32, TinkerforgeError> {
917        let mut payload = [0; 1];
918        communication_method.write_to_slice(&mut payload[0..1]);
919
920        #[allow(unused_variables)]
921        let result = self.device.get(u8::from(ServoBrickFunction::GetSendTimeoutCount), &payload).await?;
922        Ok(u32::from_le_byte_slice(result.body()))
923    }
924
925    /// Sets the baudrate for a specific Bricklet port.
926    ///
927    /// If you want to increase the throughput of Bricklets you can increase
928    /// the baudrate. If you get a high error count because of high
929    /// interference (see [`get_spitfp_error_count`]) you can decrease the
930    /// baudrate.
931    ///
932    /// If the dynamic baudrate feature is enabled, the baudrate set by this
933    /// function corresponds to the maximum baudrate (see [`set_spitfp_baudrate_config`]).
934    ///
935    /// Regulatory testing is done with the default baudrate. If CE compatibility
936    /// or similar is necessary in your applications we recommend to not change
937    /// the baudrate.
938    ///
939    ///
940    /// .. versionadded:: 2.3.2$nbsp;(Firmware)
941    pub async fn set_spitfp_baudrate(&mut self, bricklet_port: char, baudrate: u32) -> Result<(), TinkerforgeError> {
942        let mut payload = [0; 5];
943        bricklet_port.write_to_slice(&mut payload[0..1]);
944        baudrate.write_to_slice(&mut payload[1..5]);
945
946        #[allow(unused_variables)]
947        let result = self.device.set(u8::from(ServoBrickFunction::SetSpitfpBaudrate), &payload).await?;
948        Ok(())
949    }
950
951    /// Returns the baudrate for a given Bricklet port, see [`set_spitfp_baudrate`].
952    ///
953    ///
954    /// .. versionadded:: 2.3.2$nbsp;(Firmware)
955    pub async fn get_spitfp_baudrate(&mut self, bricklet_port: char) -> Result<u32, TinkerforgeError> {
956        let mut payload = [0; 1];
957        bricklet_port.write_to_slice(&mut payload[0..1]);
958
959        #[allow(unused_variables)]
960        let result = self.device.get(u8::from(ServoBrickFunction::GetSpitfpBaudrate), &payload).await?;
961        Ok(u32::from_le_byte_slice(result.body()))
962    }
963
964    /// Returns the error count for the communication between Brick and Bricklet.
965    ///
966    /// The errors are divided into
967    ///
968    /// * ACK checksum errors,
969    /// * message checksum errors,
970    /// * framing errors and
971    /// * overflow errors.
972    ///
973    /// The errors counts are for errors that occur on the Brick side. All
974    /// Bricklets have a similar function that returns the errors on the Bricklet side.
975    ///
976    ///
977    /// .. versionadded:: 2.3.2$nbsp;(Firmware)
978    pub async fn get_spitfp_error_count(&mut self, bricklet_port: char) -> Result<SpitfpErrorCount, TinkerforgeError> {
979        let mut payload = [0; 1];
980        bricklet_port.write_to_slice(&mut payload[0..1]);
981
982        #[allow(unused_variables)]
983        let result = self.device.get(u8::from(ServoBrickFunction::GetSpitfpErrorCount), &payload).await?;
984        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
985    }
986
987    /// Enables the status LED.
988    ///
989    /// The status LED is the blue LED next to the USB connector. If enabled is is
990    /// on and it flickers if data is transfered. If disabled it is always off.
991    ///
992    /// The default state is enabled.
993    ///
994    ///
995    /// .. versionadded:: 2.3.1$nbsp;(Firmware)
996    pub async fn enable_status_led(&mut self) -> Result<(), TinkerforgeError> {
997        let payload = [0; 0];
998
999        #[allow(unused_variables)]
1000        let result = self.device.set(u8::from(ServoBrickFunction::EnableStatusLed), &payload).await?;
1001        Ok(())
1002    }
1003
1004    /// Disables the status LED.
1005    ///
1006    /// The status LED is the blue LED next to the USB connector. If enabled is is
1007    /// on and it flickers if data is transfered. If disabled it is always off.
1008    ///
1009    /// The default state is enabled.
1010    ///
1011    ///
1012    /// .. versionadded:: 2.3.1$nbsp;(Firmware)
1013    pub async fn disable_status_led(&mut self) -> Result<(), TinkerforgeError> {
1014        let payload = [0; 0];
1015
1016        #[allow(unused_variables)]
1017        let result = self.device.set(u8::from(ServoBrickFunction::DisableStatusLed), &payload).await?;
1018        Ok(())
1019    }
1020
1021    /// Returns *true* if the status LED is enabled, *false* otherwise.
1022    ///
1023    ///
1024    /// .. versionadded:: 2.3.1$nbsp;(Firmware)
1025    pub async fn is_status_led_enabled(&mut self) -> Result<bool, TinkerforgeError> {
1026        let payload = [0; 0];
1027
1028        #[allow(unused_variables)]
1029        let result = self.device.get(u8::from(ServoBrickFunction::IsStatusLedEnabled), &payload).await?;
1030        Ok(bool::from_le_byte_slice(result.body()))
1031    }
1032
1033    /// Returns the firmware and protocol version and the name of the Bricklet for a
1034    /// given port.
1035    ///
1036    /// This functions sole purpose is to allow automatic flashing of v1.x.y Bricklet
1037    /// plugins.
1038    pub async fn get_protocol1_bricklet_name(&mut self, port: char) -> Result<Protocol1BrickletName, TinkerforgeError> {
1039        let mut payload = [0; 1];
1040        port.write_to_slice(&mut payload[0..1]);
1041
1042        #[allow(unused_variables)]
1043        let result = self.device.get(u8::from(ServoBrickFunction::GetProtocol1BrickletName), &payload).await?;
1044        Ok(Protocol1BrickletName::from_le_byte_slice(result.body()))
1045    }
1046
1047    /// Returns the temperature as measured inside the microcontroller. The
1048    /// value returned is not the ambient temperature!
1049    ///
1050    /// The temperature is only proportional to the real temperature and it has an
1051    /// accuracy of ±15%. Practically it is only useful as an indicator for
1052    /// temperature changes.
1053    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
1054        let payload = [0; 0];
1055
1056        #[allow(unused_variables)]
1057        let result = self.device.get(u8::from(ServoBrickFunction::GetChipTemperature), &payload).await?;
1058        Ok(i16::from_le_byte_slice(result.body()))
1059    }
1060
1061    /// Calling this function will reset the Brick. Calling this function
1062    /// on a Brick inside of a stack will reset the whole stack.
1063    ///
1064    /// After a reset you have to create new device objects,
1065    /// calling functions on the existing ones will result in
1066    /// undefined behavior!
1067    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
1068        let payload = [0; 0];
1069
1070        #[allow(unused_variables)]
1071        let result = self.device.set(u8::from(ServoBrickFunction::Reset), &payload).await?;
1072        Ok(())
1073    }
1074
1075    /// Writes 32 bytes of firmware to the bricklet attached at the given port.
1076    /// The bytes are written to the position offset * 32.
1077    ///
1078    /// This function is used by Brick Viewer during flashing. It should not be
1079    /// necessary to call it in a normal user program.
1080    pub async fn write_bricklet_plugin(&mut self, port: char, offset: u8, chunk: &[u8; 32]) -> Result<(), TinkerforgeError> {
1081        let mut payload = [0; 34];
1082        port.write_to_slice(&mut payload[0..1]);
1083        offset.write_to_slice(&mut payload[1..2]);
1084        chunk.write_to_slice(&mut payload[2..34]);
1085
1086        #[allow(unused_variables)]
1087        let result = self.device.set(u8::from(ServoBrickFunction::WriteBrickletPlugin), &payload).await?;
1088        Ok(())
1089    }
1090
1091    /// Reads 32 bytes of firmware from the bricklet attached at the given port.
1092    /// The bytes are read starting at the position offset * 32.
1093    ///
1094    /// This function is used by Brick Viewer during flashing. It should not be
1095    /// necessary to call it in a normal user program.
1096    pub async fn read_bricklet_plugin(&mut self, port: char, offset: u8) -> Result<Box<[u8; 32]>, TinkerforgeError> {
1097        let mut payload = [0; 2];
1098        port.write_to_slice(&mut payload[0..1]);
1099        offset.write_to_slice(&mut payload[1..2]);
1100
1101        #[allow(unused_variables)]
1102        let result = self.device.get(u8::from(ServoBrickFunction::ReadBrickletPlugin), &payload).await?;
1103        Ok(Box::<[u8; 32]>::from_le_byte_slice(result.body()))
1104    }
1105
1106    /// Returns the UID, the UID where the Brick is connected to,
1107    /// the position, the hardware and firmware version as well as the
1108    /// device identifier.
1109    ///
1110    /// The position is the position in the stack from '0' (bottom) to '8' (top).
1111    ///
1112    /// The device identifier numbers can be found [here](device_identifier).
1113    /// |device_identifier_constant|
1114    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
1115        let payload = [0; 0];
1116
1117        #[allow(unused_variables)]
1118        let result = self.device.get(u8::from(ServoBrickFunction::GetIdentity), &payload).await?;
1119        Ok(Identity::from_le_byte_slice(result.body()))
1120    }
1121}