tinkerforge_async/bindings/
hat_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//! HAT for Raspberry Pi with 8 Bricklets ports and real-time clock.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricks/HAT_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 HatBrickFunction {
24    SetSleepMode,
25    GetSleepMode,
26    SetBrickletPower,
27    GetBrickletPower,
28    GetVoltages,
29    SetVoltagesCallbackConfiguration,
30    GetVoltagesCallbackConfiguration,
31    SetRtcDriver,
32    GetRtcDriver,
33    GetSpitfpErrorCount,
34    SetBootloaderMode,
35    GetBootloaderMode,
36    SetWriteFirmwarePointer,
37    WriteFirmware,
38    SetStatusLedConfig,
39    GetStatusLedConfig,
40    GetChipTemperature,
41    Reset,
42    WriteUid,
43    ReadUid,
44    GetIdentity,
45    CallbackVoltages,
46}
47impl From<HatBrickFunction> for u8 {
48    fn from(fun: HatBrickFunction) -> Self {
49        match fun {
50            HatBrickFunction::SetSleepMode => 1,
51            HatBrickFunction::GetSleepMode => 2,
52            HatBrickFunction::SetBrickletPower => 3,
53            HatBrickFunction::GetBrickletPower => 4,
54            HatBrickFunction::GetVoltages => 5,
55            HatBrickFunction::SetVoltagesCallbackConfiguration => 6,
56            HatBrickFunction::GetVoltagesCallbackConfiguration => 7,
57            HatBrickFunction::SetRtcDriver => 9,
58            HatBrickFunction::GetRtcDriver => 10,
59            HatBrickFunction::GetSpitfpErrorCount => 234,
60            HatBrickFunction::SetBootloaderMode => 235,
61            HatBrickFunction::GetBootloaderMode => 236,
62            HatBrickFunction::SetWriteFirmwarePointer => 237,
63            HatBrickFunction::WriteFirmware => 238,
64            HatBrickFunction::SetStatusLedConfig => 239,
65            HatBrickFunction::GetStatusLedConfig => 240,
66            HatBrickFunction::GetChipTemperature => 242,
67            HatBrickFunction::Reset => 243,
68            HatBrickFunction::WriteUid => 248,
69            HatBrickFunction::ReadUid => 249,
70            HatBrickFunction::GetIdentity => 255,
71            HatBrickFunction::CallbackVoltages => 8,
72        }
73    }
74}
75pub const HAT_BRICK_RTC_DRIVER_PCF8523: u8 = 0;
76pub const HAT_BRICK_RTC_DRIVER_DS1338: u8 = 1;
77pub const HAT_BRICK_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
78pub const HAT_BRICK_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
79pub const HAT_BRICK_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
80pub const HAT_BRICK_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
81pub const HAT_BRICK_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
82pub const HAT_BRICK_BOOTLOADER_STATUS_OK: u8 = 0;
83pub const HAT_BRICK_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
84pub const HAT_BRICK_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
85pub const HAT_BRICK_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
86pub const HAT_BRICK_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
87pub const HAT_BRICK_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
88pub const HAT_BRICK_STATUS_LED_CONFIG_OFF: u8 = 0;
89pub const HAT_BRICK_STATUS_LED_CONFIG_ON: u8 = 1;
90pub const HAT_BRICK_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
91pub const HAT_BRICK_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
92
93#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
94pub struct SleepMode {
95    pub power_off_delay: u32,
96    pub power_off_duration: u32,
97    pub raspberry_pi_off: bool,
98    pub bricklets_off: bool,
99    pub enable_sleep_indicator: bool,
100}
101impl FromByteSlice for SleepMode {
102    fn bytes_expected() -> usize {
103        11
104    }
105    fn from_le_byte_slice(bytes: &[u8]) -> SleepMode {
106        SleepMode {
107            power_off_delay: <u32>::from_le_byte_slice(&bytes[0..4]),
108            power_off_duration: <u32>::from_le_byte_slice(&bytes[4..8]),
109            raspberry_pi_off: <bool>::from_le_byte_slice(&bytes[8..9]),
110            bricklets_off: <bool>::from_le_byte_slice(&bytes[9..10]),
111            enable_sleep_indicator: <bool>::from_le_byte_slice(&bytes[10..11]),
112        }
113    }
114}
115
116#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
117pub struct Voltages {
118    pub voltage_usb: u16,
119    pub voltage_dc: u16,
120}
121impl FromByteSlice for Voltages {
122    fn bytes_expected() -> usize {
123        4
124    }
125    fn from_le_byte_slice(bytes: &[u8]) -> Voltages {
126        Voltages { voltage_usb: <u16>::from_le_byte_slice(&bytes[0..2]), voltage_dc: <u16>::from_le_byte_slice(&bytes[2..4]) }
127    }
128}
129
130#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
131pub struct VoltagesCallbackConfiguration {
132    pub period: u32,
133    pub value_has_to_change: bool,
134}
135impl FromByteSlice for VoltagesCallbackConfiguration {
136    fn bytes_expected() -> usize {
137        5
138    }
139    fn from_le_byte_slice(bytes: &[u8]) -> VoltagesCallbackConfiguration {
140        VoltagesCallbackConfiguration {
141            period: <u32>::from_le_byte_slice(&bytes[0..4]),
142            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
143        }
144    }
145}
146
147#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
148pub struct VoltagesEvent {
149    pub voltage_usb: u16,
150    pub voltage_dc: u16,
151}
152impl FromByteSlice for VoltagesEvent {
153    fn bytes_expected() -> usize {
154        4
155    }
156    fn from_le_byte_slice(bytes: &[u8]) -> VoltagesEvent {
157        VoltagesEvent { voltage_usb: <u16>::from_le_byte_slice(&bytes[0..2]), voltage_dc: <u16>::from_le_byte_slice(&bytes[2..4]) }
158    }
159}
160
161#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
162pub struct SpitfpErrorCount {
163    pub error_count_ack_checksum: u32,
164    pub error_count_message_checksum: u32,
165    pub error_count_frame: u32,
166    pub error_count_overflow: u32,
167}
168impl FromByteSlice for SpitfpErrorCount {
169    fn bytes_expected() -> usize {
170        16
171    }
172    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
173        SpitfpErrorCount {
174            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
175            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
176            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
177            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
178        }
179    }
180}
181
182#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
183pub struct Identity {
184    pub uid: String,
185    pub connected_uid: String,
186    pub position: char,
187    pub hardware_version: [u8; 3],
188    pub firmware_version: [u8; 3],
189    pub device_identifier: u16,
190}
191impl FromByteSlice for Identity {
192    fn bytes_expected() -> usize {
193        25
194    }
195    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
196        Identity {
197            uid: <String>::from_le_byte_slice(&bytes[0..8]),
198            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
199            position: <char>::from_le_byte_slice(&bytes[16..17]),
200            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
201            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
202            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
203        }
204    }
205}
206
207/// HAT for Raspberry Pi with 8 Bricklets ports and real-time clock
208#[derive(Clone)]
209pub struct HatBrick {
210    device: Device,
211}
212impl HatBrick {
213    pub const DEVICE_IDENTIFIER: u16 = 111;
214    pub const DEVICE_DISPLAY_NAME: &'static str = "HAT Brick";
215    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
216    pub fn new(uid: Uid, connection: AsyncIpConnection) -> HatBrick {
217        let mut result = HatBrick { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
218        result.device.response_expected[u8::from(HatBrickFunction::SetSleepMode) as usize] = ResponseExpectedFlag::False;
219        result.device.response_expected[u8::from(HatBrickFunction::GetSleepMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
220        result.device.response_expected[u8::from(HatBrickFunction::SetBrickletPower) as usize] = ResponseExpectedFlag::False;
221        result.device.response_expected[u8::from(HatBrickFunction::GetBrickletPower) as usize] = ResponseExpectedFlag::AlwaysTrue;
222        result.device.response_expected[u8::from(HatBrickFunction::GetVoltages) as usize] = ResponseExpectedFlag::AlwaysTrue;
223        result.device.response_expected[u8::from(HatBrickFunction::SetVoltagesCallbackConfiguration) as usize] = ResponseExpectedFlag::True;
224        result.device.response_expected[u8::from(HatBrickFunction::GetVoltagesCallbackConfiguration) as usize] =
225            ResponseExpectedFlag::AlwaysTrue;
226        result.device.response_expected[u8::from(HatBrickFunction::SetRtcDriver) as usize] = ResponseExpectedFlag::False;
227        result.device.response_expected[u8::from(HatBrickFunction::GetRtcDriver) as usize] = ResponseExpectedFlag::AlwaysTrue;
228        result.device.response_expected[u8::from(HatBrickFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
229        result.device.response_expected[u8::from(HatBrickFunction::SetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
230        result.device.response_expected[u8::from(HatBrickFunction::GetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
231        result.device.response_expected[u8::from(HatBrickFunction::SetWriteFirmwarePointer) as usize] = ResponseExpectedFlag::False;
232        result.device.response_expected[u8::from(HatBrickFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
233        result.device.response_expected[u8::from(HatBrickFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
234        result.device.response_expected[u8::from(HatBrickFunction::GetStatusLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
235        result.device.response_expected[u8::from(HatBrickFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
236        result.device.response_expected[u8::from(HatBrickFunction::Reset) as usize] = ResponseExpectedFlag::False;
237        result.device.response_expected[u8::from(HatBrickFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
238        result.device.response_expected[u8::from(HatBrickFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
239        result.device.response_expected[u8::from(HatBrickFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
240        result
241    }
242
243    /// Returns the response expected flag for the function specified by the function ID parameter.
244    /// It is true if the function is expected to send a response, false otherwise.
245    ///
246    /// For getter functions this is enabled by default and cannot be disabled, because those
247    /// functions will always send a response. For callback configuration functions it is enabled
248    /// by default too, but can be disabled by [`set_response_expected`](crate::hat_brick::HatBrick::set_response_expected).
249    /// For setter functions it is disabled by default and can be enabled.
250    ///
251    /// Enabling the response expected flag for a setter function allows to detect timeouts
252    /// and other error conditions calls of this setter as well. The device will then send a response
253    /// for this purpose. If this flag is disabled for a setter function then no response is sent
254    /// and errors are silently ignored, because they cannot be detected.
255    ///
256    /// See [`set_response_expected`](crate::hat_brick::HatBrick::set_response_expected) for the list of function ID constants available for this function.
257    pub fn get_response_expected(&mut self, fun: HatBrickFunction) -> Result<bool, GetResponseExpectedError> {
258        self.device.get_response_expected(u8::from(fun))
259    }
260
261    /// Changes the response expected flag of the function specified by the function ID parameter.
262    /// This flag can only be changed for setter (default value: false) and callback configuration
263    /// functions (default value: true). For getter functions it is always enabled.
264    ///
265    /// Enabling the response expected flag for a setter function allows to detect timeouts and
266    /// other error conditions calls of this setter as well. The device will then send a response
267    /// for this purpose. If this flag is disabled for a setter function then no response is sent
268    /// and errors are silently ignored, because they cannot be detected.
269    pub fn set_response_expected(&mut self, fun: HatBrickFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
270        self.device.set_response_expected(u8::from(fun), response_expected)
271    }
272
273    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
274    pub fn set_response_expected_all(&mut self, response_expected: bool) {
275        self.device.set_response_expected_all(response_expected)
276    }
277
278    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
279    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
280    pub fn get_api_version(&self) -> [u8; 3] {
281        self.device.api_version
282    }
283
284    /// This receiver is triggered periodically according to the configuration set by
285    /// [`set_voltages_callback_configuration`].
286    ///
287    /// The parameters are the same as [`get_voltages`].
288    ///
289    /// [`get_voltages`]: #method.get_voltages
290    /// [`set_voltages_callback_configuration`]: #method.set_voltages_callback_configuration
291    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
292    pub async fn get_voltages_callback_receiver(&mut self) -> impl Stream<Item = VoltagesEvent> {
293        self.device
294            .get_callback_receiver(u8::from(HatBrickFunction::CallbackVoltages))
295            .await
296            .map(|p| VoltagesEvent::from_le_byte_slice(p.body()))
297    }
298
299    /// Sets the sleep mode.
300    ///
301    /// # Note
302    ///  Calling this function will cut the Raspberry Pi's power after Power Off Delay seconds.
303    ///  You have to shut down the operating system yourself, e.g. by calling 'sudo shutdown -h now'.
304    ///
305    /// Parameters:
306    ///
307    /// * Power Off Delay: Time before the RPi/Bricklets are powered off.
308    /// * Power Off Duration: Duration that the RPi/Bricklets stay powered off.
309    /// * Raspberry Pi Off: RPi is powered off if set to true.
310    /// * Bricklets Off: Bricklets are powered off if set to true.
311    /// * Enable Sleep Indicator: If set to true, the status LED will blink in a 1s interval
312    ///   during the whole power off duration. This will draw additional 0.3mA.
313    ///
314    /// Example: To turn RPi and Bricklets off in 5 seconds for 10 minutes with sleep
315    /// indicator enabled, call (5, 60*10, true, true, true).
316    ///
317    /// This function can also be used to implement a watchdog. To do this you can
318    /// write a program that calls this function once per second in a loop with
319    /// (10, 2, true, false, false). If the RPi crashes or gets stuck
320    /// the HAT will reset the RPi after 10 seconds.
321    pub async fn set_sleep_mode(
322        &mut self,
323        power_off_delay: u32,
324        power_off_duration: u32,
325        raspberry_pi_off: bool,
326        bricklets_off: bool,
327        enable_sleep_indicator: bool,
328    ) -> Result<(), TinkerforgeError> {
329        let mut payload = [0; 11];
330        power_off_delay.write_to_slice(&mut payload[0..4]);
331        power_off_duration.write_to_slice(&mut payload[4..8]);
332        raspberry_pi_off.write_to_slice(&mut payload[8..9]);
333        bricklets_off.write_to_slice(&mut payload[9..10]);
334        enable_sleep_indicator.write_to_slice(&mut payload[10..11]);
335
336        #[allow(unused_variables)]
337        let result = self.device.set(u8::from(HatBrickFunction::SetSleepMode), &payload).await?;
338        Ok(())
339    }
340
341    /// Returns the sleep mode settings as set by [`set_sleep_mode`].
342    pub async fn get_sleep_mode(&mut self) -> Result<SleepMode, TinkerforgeError> {
343        let payload = [0; 0];
344
345        #[allow(unused_variables)]
346        let result = self.device.get(u8::from(HatBrickFunction::GetSleepMode), &payload).await?;
347        Ok(SleepMode::from_le_byte_slice(result.body()))
348    }
349
350    /// Set to true/false to turn the power supply of the connected Bricklets on/off.
351    pub async fn set_bricklet_power(&mut self, bricklet_power: bool) -> Result<(), TinkerforgeError> {
352        let mut payload = [0; 1];
353        bricklet_power.write_to_slice(&mut payload[0..1]);
354
355        #[allow(unused_variables)]
356        let result = self.device.set(u8::from(HatBrickFunction::SetBrickletPower), &payload).await?;
357        Ok(())
358    }
359
360    /// Returns the power status of the connected Bricklets as set by [`set_bricklet_power`].
361    pub async fn get_bricklet_power(&mut self) -> Result<bool, TinkerforgeError> {
362        let payload = [0; 0];
363
364        #[allow(unused_variables)]
365        let result = self.device.get(u8::from(HatBrickFunction::GetBrickletPower), &payload).await?;
366        Ok(bool::from_le_byte_slice(result.body()))
367    }
368
369    /// Returns the USB supply voltage and the DC input supply voltage.
370    ///
371    /// There are three possible combinations:
372    ///
373    /// * Only USB connected: The USB supply voltage will be fed back to the
374    ///   DC input connector. You will read the USB voltage and a slightly lower
375    ///   voltage on the DC input.
376    /// * Only DC input connected: The DC voltage will not be fed back to the
377    ///   USB connector. You will read the DC input voltage and the USB voltage
378    ///   will be 0.
379    /// * USB and DC input connected: You will read both voltages. In this case
380    ///   the USB supply will be without load, but it will work as backup if you
381    ///   disconnect the DC input (or if the DC input voltage falls below the
382    ///   USB voltage).
383    pub async fn get_voltages(&mut self) -> Result<Voltages, TinkerforgeError> {
384        let payload = [0; 0];
385
386        #[allow(unused_variables)]
387        let result = self.device.get(u8::from(HatBrickFunction::GetVoltages), &payload).await?;
388        Ok(Voltages::from_le_byte_slice(result.body()))
389    }
390
391    /// The period is the period with which the [`get_voltages_callback_receiver`]
392    /// receiver is triggered periodically. A value of 0 turns the receiver off.
393    ///
394    /// If the `value has to change`-parameter is set to true, the receiver is only
395    /// triggered after the value has changed. If the value didn't change within the
396    /// period, the receiver is triggered immediately on change.
397    ///
398    /// If it is set to false, the receiver is continuously triggered with the period,
399    /// independent of the value.
400    ///
401    ///
402    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
403    pub async fn set_voltages_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
404        let mut payload = [0; 5];
405        period.write_to_slice(&mut payload[0..4]);
406        value_has_to_change.write_to_slice(&mut payload[4..5]);
407
408        #[allow(unused_variables)]
409        let result = self.device.set(u8::from(HatBrickFunction::SetVoltagesCallbackConfiguration), &payload).await?;
410        Ok(())
411    }
412
413    /// Returns the receiver configuration as set by
414    /// [`set_voltages_callback_configuration`].
415    ///
416    ///
417    /// .. versionadded:: 2.0.1$nbsp;(Firmware)
418    pub async fn get_voltages_callback_configuration(&mut self) -> Result<VoltagesCallbackConfiguration, TinkerforgeError> {
419        let payload = [0; 0];
420
421        #[allow(unused_variables)]
422        let result = self.device.get(u8::from(HatBrickFunction::GetVoltagesCallbackConfiguration), &payload).await?;
423        Ok(VoltagesCallbackConfiguration::from_le_byte_slice(result.body()))
424    }
425
426    /// Configures the RTC driver that is given to the Raspberry Pi to be used.
427    /// Currently there are two different RTCs used:
428    ///
429    /// * Hardware version <= 1.5: PCF8523
430    /// * Hardware version 1.6: DS1338
431    ///
432    /// The correct driver will be set during factory flashing by Tinkerforge.
433    ///
434    ///
435    /// .. versionadded:: 2.0.3$nbsp;(Firmware)
436    ///
437    /// Associated constants:
438    /// * HAT_BRICK_RTC_DRIVER_PCF8523
439    ///	* HAT_BRICK_RTC_DRIVER_DS1338
440    pub async fn set_rtc_driver(&mut self, rtc_driver: u8) -> Result<(), TinkerforgeError> {
441        let mut payload = [0; 1];
442        rtc_driver.write_to_slice(&mut payload[0..1]);
443
444        #[allow(unused_variables)]
445        let result = self.device.set(u8::from(HatBrickFunction::SetRtcDriver), &payload).await?;
446        Ok(())
447    }
448
449    /// Returns the RTC driver as set by [`set_rtc_driver`].
450    ///
451    ///
452    /// .. versionadded:: 2.0.3$nbsp;(Firmware)
453    ///
454    /// Associated constants:
455    /// * HAT_BRICK_RTC_DRIVER_PCF8523
456    ///	* HAT_BRICK_RTC_DRIVER_DS1338
457    pub async fn get_rtc_driver(&mut self) -> Result<u8, TinkerforgeError> {
458        let payload = [0; 0];
459
460        #[allow(unused_variables)]
461        let result = self.device.get(u8::from(HatBrickFunction::GetRtcDriver), &payload).await?;
462        Ok(u8::from_le_byte_slice(result.body()))
463    }
464
465    /// Returns the error count for the communication between Brick and Bricklet.
466    ///
467    /// The errors are divided into
468    ///
469    /// * ACK checksum errors,
470    /// * message checksum errors,
471    /// * framing errors and
472    /// * overflow errors.
473    ///
474    /// The errors counts are for errors that occur on the Bricklet side. All
475    /// Bricks have a similar function that returns the errors on the Brick side.
476    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
477        let payload = [0; 0];
478
479        #[allow(unused_variables)]
480        let result = self.device.get(u8::from(HatBrickFunction::GetSpitfpErrorCount), &payload).await?;
481        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
482    }
483
484    /// Sets the bootloader mode and returns the status after the requested
485    /// mode change was instigated.
486    ///
487    /// You can change from bootloader mode to firmware mode and vice versa. A change
488    /// from bootloader mode to firmware mode will only take place if the entry function,
489    /// device identifier and CRC are present and correct.
490    ///
491    /// This function is used by Brick Viewer during flashing. It should not be
492    /// necessary to call it in a normal user program.
493    ///
494    /// Associated constants:
495    /// * HAT_BRICK_BOOTLOADER_MODE_BOOTLOADER
496    ///	* HAT_BRICK_BOOTLOADER_MODE_FIRMWARE
497    ///	* HAT_BRICK_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
498    ///	* HAT_BRICK_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
499    ///	* HAT_BRICK_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
500    ///	* HAT_BRICK_BOOTLOADER_STATUS_OK
501    ///	* HAT_BRICK_BOOTLOADER_STATUS_INVALID_MODE
502    ///	* HAT_BRICK_BOOTLOADER_STATUS_NO_CHANGE
503    ///	* HAT_BRICK_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
504    ///	* HAT_BRICK_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
505    ///	* HAT_BRICK_BOOTLOADER_STATUS_CRC_MISMATCH
506    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
507        let mut payload = [0; 1];
508        mode.write_to_slice(&mut payload[0..1]);
509
510        #[allow(unused_variables)]
511        let result = self.device.get(u8::from(HatBrickFunction::SetBootloaderMode), &payload).await?;
512        Ok(u8::from_le_byte_slice(result.body()))
513    }
514
515    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
516    ///
517    /// Associated constants:
518    /// * HAT_BRICK_BOOTLOADER_MODE_BOOTLOADER
519    ///	* HAT_BRICK_BOOTLOADER_MODE_FIRMWARE
520    ///	* HAT_BRICK_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
521    ///	* HAT_BRICK_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
522    ///	* HAT_BRICK_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
523    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
524        let payload = [0; 0];
525
526        #[allow(unused_variables)]
527        let result = self.device.get(u8::from(HatBrickFunction::GetBootloaderMode), &payload).await?;
528        Ok(u8::from_le_byte_slice(result.body()))
529    }
530
531    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
532    /// to be increased by chunks of size 64. The data is written to flash
533    /// every 4 chunks (which equals to one page of size 256).
534    ///
535    /// This function is used by Brick Viewer during flashing. It should not be
536    /// necessary to call it in a normal user program.
537    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
538        let mut payload = [0; 4];
539        pointer.write_to_slice(&mut payload[0..4]);
540
541        #[allow(unused_variables)]
542        let result = self.device.set(u8::from(HatBrickFunction::SetWriteFirmwarePointer), &payload).await?;
543        Ok(())
544    }
545
546    /// Writes 64 Bytes of firmware at the position as written by
547    /// [`set_write_firmware_pointer`] before. The firmware is written
548    /// to flash every 4 chunks.
549    ///
550    /// You can only write firmware in bootloader mode.
551    ///
552    /// This function is used by Brick Viewer during flashing. It should not be
553    /// necessary to call it in a normal user program.
554    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
555        let mut payload = [0; 64];
556        data.write_to_slice(&mut payload[0..64]);
557
558        #[allow(unused_variables)]
559        let result = self.device.get(u8::from(HatBrickFunction::WriteFirmware), &payload).await?;
560        Ok(u8::from_le_byte_slice(result.body()))
561    }
562
563    /// Sets the status LED configuration. By default the LED shows
564    /// communication traffic between Brick and Bricklet, it flickers once
565    /// for every 10 received data packets.
566    ///
567    /// You can also turn the LED permanently on/off or show a heartbeat.
568    ///
569    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
570    ///
571    /// Associated constants:
572    /// * HAT_BRICK_STATUS_LED_CONFIG_OFF
573    ///	* HAT_BRICK_STATUS_LED_CONFIG_ON
574    ///	* HAT_BRICK_STATUS_LED_CONFIG_SHOW_HEARTBEAT
575    ///	* HAT_BRICK_STATUS_LED_CONFIG_SHOW_STATUS
576    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
577        let mut payload = [0; 1];
578        config.write_to_slice(&mut payload[0..1]);
579
580        #[allow(unused_variables)]
581        let result = self.device.set(u8::from(HatBrickFunction::SetStatusLedConfig), &payload).await?;
582        Ok(())
583    }
584
585    /// Returns the configuration as set by [`set_status_led_config`]
586    ///
587    /// Associated constants:
588    /// * HAT_BRICK_STATUS_LED_CONFIG_OFF
589    ///	* HAT_BRICK_STATUS_LED_CONFIG_ON
590    ///	* HAT_BRICK_STATUS_LED_CONFIG_SHOW_HEARTBEAT
591    ///	* HAT_BRICK_STATUS_LED_CONFIG_SHOW_STATUS
592    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
593        let payload = [0; 0];
594
595        #[allow(unused_variables)]
596        let result = self.device.get(u8::from(HatBrickFunction::GetStatusLedConfig), &payload).await?;
597        Ok(u8::from_le_byte_slice(result.body()))
598    }
599
600    /// Returns the temperature as measured inside the microcontroller. The
601    /// value returned is not the ambient temperature!
602    ///
603    /// The temperature is only proportional to the real temperature and it has bad
604    /// accuracy. Practically it is only useful as an indicator for
605    /// temperature changes.
606    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
607        let payload = [0; 0];
608
609        #[allow(unused_variables)]
610        let result = self.device.get(u8::from(HatBrickFunction::GetChipTemperature), &payload).await?;
611        Ok(i16::from_le_byte_slice(result.body()))
612    }
613
614    /// Calling this function will reset the Bricklet. All configurations
615    /// will be lost.
616    ///
617    /// After a reset you have to create new device objects,
618    /// calling functions on the existing ones will result in
619    /// undefined behavior!
620    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
621        let payload = [0; 0];
622
623        #[allow(unused_variables)]
624        let result = self.device.set(u8::from(HatBrickFunction::Reset), &payload).await?;
625        Ok(())
626    }
627
628    /// Writes a new UID into flash. If you want to set a new UID
629    /// you have to decode the Base58 encoded UID string into an
630    /// integer first.
631    ///
632    /// We recommend that you use Brick Viewer to change the UID.
633    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
634        let mut payload = [0; 4];
635        uid.write_to_slice(&mut payload[0..4]);
636
637        #[allow(unused_variables)]
638        let result = self.device.set(u8::from(HatBrickFunction::WriteUid), &payload).await?;
639        Ok(())
640    }
641
642    /// Returns the current UID as an integer. Encode as
643    /// Base58 to get the usual string version.
644    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
645        let payload = [0; 0];
646
647        #[allow(unused_variables)]
648        let result = self.device.get(u8::from(HatBrickFunction::ReadUid), &payload).await?;
649        Ok(u32::from_le_byte_slice(result.body()))
650    }
651
652    /// Returns the UID, the UID where the HAT is connected to
653    /// (typically '0' as the HAT is the root device in the topology),
654    /// the position, the hardware and firmware version as well as the
655    /// device identifier.
656    ///
657    /// The HAT (Zero) Brick is always at position 'i'.
658    ///
659    /// The device identifier numbers can be found [here](device_identifier).
660    /// |device_identifier_constant|
661    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
662        let payload = [0; 0];
663
664        #[allow(unused_variables)]
665        let result = self.device.get(u8::from(HatBrickFunction::GetIdentity), &payload).await?;
666        Ok(Identity::from_le_byte_slice(result.body()))
667    }
668}