tinkerforge_async/bindings/
led_strip_v2_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! Controls up to 2048 RGB(W) LEDs.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/LEDStripV2_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, converting_receiver::BrickletRecvTimeoutError, device::*, error::TinkerforgeError,
17    ip_connection::async_io::AsyncIpConnection, low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum LedStripV2BrickletFunction {
24    SetLedValuesLowLevel,
25    GetLedValuesLowLevel,
26    SetFrameDuration,
27    GetFrameDuration,
28    GetSupplyVoltage,
29    SetClockFrequency,
30    GetClockFrequency,
31    SetChipType,
32    GetChipType,
33    SetChannelMapping,
34    GetChannelMapping,
35    SetFrameStartedCallbackConfiguration,
36    GetFrameStartedCallbackConfiguration,
37    GetSpitfpErrorCount,
38    SetBootloaderMode,
39    GetBootloaderMode,
40    SetWriteFirmwarePointer,
41    WriteFirmware,
42    SetStatusLedConfig,
43    GetStatusLedConfig,
44    GetChipTemperature,
45    Reset,
46    WriteUid,
47    ReadUid,
48    GetIdentity,
49    CallbackFrameStarted,
50}
51impl From<LedStripV2BrickletFunction> for u8 {
52    fn from(fun: LedStripV2BrickletFunction) -> Self {
53        match fun {
54            LedStripV2BrickletFunction::SetLedValuesLowLevel => 1,
55            LedStripV2BrickletFunction::GetLedValuesLowLevel => 2,
56            LedStripV2BrickletFunction::SetFrameDuration => 3,
57            LedStripV2BrickletFunction::GetFrameDuration => 4,
58            LedStripV2BrickletFunction::GetSupplyVoltage => 5,
59            LedStripV2BrickletFunction::SetClockFrequency => 7,
60            LedStripV2BrickletFunction::GetClockFrequency => 8,
61            LedStripV2BrickletFunction::SetChipType => 9,
62            LedStripV2BrickletFunction::GetChipType => 10,
63            LedStripV2BrickletFunction::SetChannelMapping => 11,
64            LedStripV2BrickletFunction::GetChannelMapping => 12,
65            LedStripV2BrickletFunction::SetFrameStartedCallbackConfiguration => 13,
66            LedStripV2BrickletFunction::GetFrameStartedCallbackConfiguration => 14,
67            LedStripV2BrickletFunction::GetSpitfpErrorCount => 234,
68            LedStripV2BrickletFunction::SetBootloaderMode => 235,
69            LedStripV2BrickletFunction::GetBootloaderMode => 236,
70            LedStripV2BrickletFunction::SetWriteFirmwarePointer => 237,
71            LedStripV2BrickletFunction::WriteFirmware => 238,
72            LedStripV2BrickletFunction::SetStatusLedConfig => 239,
73            LedStripV2BrickletFunction::GetStatusLedConfig => 240,
74            LedStripV2BrickletFunction::GetChipTemperature => 242,
75            LedStripV2BrickletFunction::Reset => 243,
76            LedStripV2BrickletFunction::WriteUid => 248,
77            LedStripV2BrickletFunction::ReadUid => 249,
78            LedStripV2BrickletFunction::GetIdentity => 255,
79            LedStripV2BrickletFunction::CallbackFrameStarted => 6,
80        }
81    }
82}
83pub const LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2801: u16 = 2801;
84pub const LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2811: u16 = 2811;
85pub const LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2812: u16 = 2812;
86pub const LED_STRIP_V2_BRICKLET_CHIP_TYPE_LPD8806: u16 = 8806;
87pub const LED_STRIP_V2_BRICKLET_CHIP_TYPE_APA102: u16 = 102;
88pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGB: u8 = 6;
89pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBG: u8 = 9;
90pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRG: u8 = 33;
91pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGR: u8 = 36;
92pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRB: u8 = 18;
93pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBR: u8 = 24;
94pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGBW: u8 = 27;
95pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGWB: u8 = 30;
96pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBGW: u8 = 39;
97pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBWG: u8 = 45;
98pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RWGB: u8 = 54;
99pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RWBG: u8 = 57;
100pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRWB: u8 = 78;
101pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRBW: u8 = 75;
102pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBWR: u8 = 108;
103pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBRW: u8 = 99;
104pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GWBR: u8 = 120;
105pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GWRB: u8 = 114;
106pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRGW: u8 = 135;
107pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRWG: u8 = 141;
108pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGRW: u8 = 147;
109pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGWR: u8 = 156;
110pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BWRG: u8 = 177;
111pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BWGR: u8 = 180;
112pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WRBG: u8 = 201;
113pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WRGB: u8 = 198;
114pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WGBR: u8 = 216;
115pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WGRB: u8 = 210;
116pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WBGR: u8 = 228;
117pub const LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WBRG: u8 = 225;
118pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
119pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
120pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
121pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
122pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
123pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
124pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
125pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
126pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
127pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
128pub const LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
129pub const LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
130pub const LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
131pub const LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
132pub const LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
133
134#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
135pub struct SetLedValuesLowLevel {}
136impl FromByteSlice for SetLedValuesLowLevel {
137    fn bytes_expected() -> usize {
138        0
139    }
140    fn from_le_byte_slice(_bytes: &[u8]) -> SetLedValuesLowLevel {
141        SetLedValuesLowLevel {}
142    }
143}
144
145#[derive(Clone, Copy)]
146pub struct LedValuesLowLevel {
147    pub value_length: u16,
148    pub value_chunk_offset: u16,
149    pub value_chunk_data: [u8; 60],
150}
151impl FromByteSlice for LedValuesLowLevel {
152    fn bytes_expected() -> usize {
153        64
154    }
155    fn from_le_byte_slice(bytes: &[u8]) -> LedValuesLowLevel {
156        LedValuesLowLevel {
157            value_length: <u16>::from_le_byte_slice(&bytes[0..2]),
158            value_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
159            value_chunk_data: <[u8; 60]>::from_le_byte_slice(&bytes[4..64]),
160        }
161    }
162}
163impl LowLevelRead<u8, LedValuesResult> for LedValuesLowLevel {
164    fn ll_message_length(&self) -> usize {
165        self.value_length as usize
166    }
167
168    fn ll_message_chunk_offset(&self) -> usize {
169        self.value_chunk_offset as usize
170    }
171
172    fn ll_message_chunk_data(&self) -> &[u8] {
173        &self.value_chunk_data
174    }
175
176    fn get_result(&self) -> LedValuesResult {
177        LedValuesResult {}
178    }
179}
180
181#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
182pub struct SpitfpErrorCount {
183    pub error_count_ack_checksum: u32,
184    pub error_count_message_checksum: u32,
185    pub error_count_frame: u32,
186    pub error_count_overflow: u32,
187}
188impl FromByteSlice for SpitfpErrorCount {
189    fn bytes_expected() -> usize {
190        16
191    }
192    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
193        SpitfpErrorCount {
194            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
195            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
196            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
197            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
198        }
199    }
200}
201
202#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
203pub struct Identity {
204    pub uid: String,
205    pub connected_uid: String,
206    pub position: char,
207    pub hardware_version: [u8; 3],
208    pub firmware_version: [u8; 3],
209    pub device_identifier: u16,
210}
211impl FromByteSlice for Identity {
212    fn bytes_expected() -> usize {
213        25
214    }
215    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
216        Identity {
217            uid: <String>::from_le_byte_slice(&bytes[0..8]),
218            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
219            position: <char>::from_le_byte_slice(&bytes[16..17]),
220            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
221            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
222            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
223        }
224    }
225}
226
227#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
228pub struct SetLedValuesResult {}
229
230#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
231pub struct LedValuesResult {}
232
233/// Controls up to 2048 RGB(W) LEDs
234#[derive(Clone)]
235pub struct LedStripV2Bricklet {
236    device: Device,
237}
238impl LedStripV2Bricklet {
239    pub const DEVICE_IDENTIFIER: u16 = 2103;
240    pub const DEVICE_DISPLAY_NAME: &'static str = "LED Strip Bricklet 2.0";
241    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
242    pub fn new(uid: Uid, connection: AsyncIpConnection) -> LedStripV2Bricklet {
243        let mut result = LedStripV2Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
244        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetLedValuesLowLevel) as usize] = ResponseExpectedFlag::True;
245        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetLedValuesLowLevel) as usize] =
246            ResponseExpectedFlag::AlwaysTrue;
247        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetFrameDuration) as usize] = ResponseExpectedFlag::False;
248        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetFrameDuration) as usize] = ResponseExpectedFlag::AlwaysTrue;
249        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetSupplyVoltage) as usize] = ResponseExpectedFlag::AlwaysTrue;
250        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetClockFrequency) as usize] = ResponseExpectedFlag::False;
251        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetClockFrequency) as usize] =
252            ResponseExpectedFlag::AlwaysTrue;
253        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetChipType) as usize] = ResponseExpectedFlag::False;
254        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetChipType) as usize] = ResponseExpectedFlag::AlwaysTrue;
255        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetChannelMapping) as usize] = ResponseExpectedFlag::False;
256        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetChannelMapping) as usize] =
257            ResponseExpectedFlag::AlwaysTrue;
258        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetFrameStartedCallbackConfiguration) as usize] =
259            ResponseExpectedFlag::True;
260        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetFrameStartedCallbackConfiguration) as usize] =
261            ResponseExpectedFlag::AlwaysTrue;
262        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetSpitfpErrorCount) as usize] =
263            ResponseExpectedFlag::AlwaysTrue;
264        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetBootloaderMode) as usize] =
265            ResponseExpectedFlag::AlwaysTrue;
266        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetBootloaderMode) as usize] =
267            ResponseExpectedFlag::AlwaysTrue;
268        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetWriteFirmwarePointer) as usize] =
269            ResponseExpectedFlag::False;
270        result.device.response_expected[u8::from(LedStripV2BrickletFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
271        result.device.response_expected[u8::from(LedStripV2BrickletFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
272        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetStatusLedConfig) as usize] =
273            ResponseExpectedFlag::AlwaysTrue;
274        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetChipTemperature) as usize] =
275            ResponseExpectedFlag::AlwaysTrue;
276        result.device.response_expected[u8::from(LedStripV2BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
277        result.device.response_expected[u8::from(LedStripV2BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
278        result.device.response_expected[u8::from(LedStripV2BrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
279        result.device.response_expected[u8::from(LedStripV2BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
280        result
281    }
282
283    /// Returns the response expected flag for the function specified by the function ID parameter.
284    /// It is true if the function is expected to send a response, false otherwise.
285    ///
286    /// For getter functions this is enabled by default and cannot be disabled, because those
287    /// functions will always send a response. For callback configuration functions it is enabled
288    /// by default too, but can be disabled by [`set_response_expected`](crate::led_strip_v2_bricklet::LedStripV2Bricklet::set_response_expected).
289    /// For setter functions it is disabled by default and can be enabled.
290    ///
291    /// Enabling the response expected flag for a setter function allows to detect timeouts
292    /// and other error conditions calls of this setter as well. The device will then send a response
293    /// for this purpose. If this flag is disabled for a setter function then no response is sent
294    /// and errors are silently ignored, because they cannot be detected.
295    ///
296    /// See [`set_response_expected`](crate::led_strip_v2_bricklet::LedStripV2Bricklet::set_response_expected) for the list of function ID constants available for this function.
297    pub fn get_response_expected(&mut self, fun: LedStripV2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
298        self.device.get_response_expected(u8::from(fun))
299    }
300
301    /// Changes the response expected flag of the function specified by the function ID parameter.
302    /// This flag can only be changed for setter (default value: false) and callback configuration
303    /// functions (default value: true). For getter functions it is always enabled.
304    ///
305    /// Enabling the response expected flag for a setter function allows to detect timeouts and
306    /// other error conditions calls of this setter as well. The device will then send a response
307    /// for this purpose. If this flag is disabled for a setter function then no response is sent
308    /// and errors are silently ignored, because they cannot be detected.
309    pub fn set_response_expected(
310        &mut self,
311        fun: LedStripV2BrickletFunction,
312        response_expected: bool,
313    ) -> Result<(), SetResponseExpectedError> {
314        self.device.set_response_expected(u8::from(fun), response_expected)
315    }
316
317    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
318    pub fn set_response_expected_all(&mut self, response_expected: bool) {
319        self.device.set_response_expected_all(response_expected)
320    }
321
322    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
323    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
324    pub fn get_api_version(&self) -> [u8; 3] {
325        self.device.api_version
326    }
327
328    /// This receiver is triggered directly after a new frame render is started.
329    /// The parameter is the number of LEDs in that frame.
330    ///
331    /// You should send the data for the next frame directly after this receiver
332    /// was triggered.
333    ///
334    /// For an explanation of the general approach see [`set_led_values`].
335    ///
336    /// [`set_led_values`]: #method.set_led_values
337    pub async fn get_frame_started_callback_receiver(&mut self) -> impl Stream<Item = u16> {
338        self.device
339            .get_callback_receiver(u8::from(LedStripV2BrickletFunction::CallbackFrameStarted))
340            .await
341            .map(|p| u16::from_le_byte_slice(p.body()))
342    }
343
344    /// Sets the RGB(W) values for the LEDs starting from *index*.
345    /// You can set at most 2048 RGB values or 1536 RGBW values (6144 byte each).
346    ///
347    /// To make the colors show correctly you need to configure the chip type
348    /// (see [`set_chip_type`]) and a channel mapping (see [`set_channel_mapping`])
349    /// according to the connected LEDs.
350    ///
351    /// If the channel mapping has 3 colors, you need to give the data in the sequence
352    /// RGBRGBRGB... if the channel mapping has 4 colors you need to give data in the
353    /// sequence RGBWRGBWRGBW...
354    ///
355    /// The data is double buffered and the colors will be transfered to the
356    /// LEDs when the next frame duration ends (see [`set_frame_duration`]).
357    ///
358    /// Generic approach:
359    ///
360    /// * Set the frame duration to a value that represents the number of frames per
361    ///   second you want to achieve.
362    /// * Set all of the LED colors for one frame.
363    /// * Wait for the [`get_frame_started_callback_receiver`] receiver.
364    /// * Set all of the LED colors for next frame.
365    /// * Wait for the [`get_frame_started_callback_receiver`] receiver.
366    /// * And so on.
367    ///
368    /// This approach ensures that you can change the LED colors with a fixed frame rate.
369    pub async fn set_led_values_low_level(
370        &mut self,
371        index: u16,
372        value_length: u16,
373        value_chunk_offset: u16,
374        value_chunk_data: &[u8; 58],
375    ) -> Result<SetLedValuesLowLevel, TinkerforgeError> {
376        let mut payload = [0; 64];
377        index.write_to_slice(&mut payload[0..2]);
378        value_length.write_to_slice(&mut payload[2..4]);
379        value_chunk_offset.write_to_slice(&mut payload[4..6]);
380        value_chunk_data.write_to_slice(&mut payload[6..64]);
381
382        #[allow(unused_variables)]
383        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetLedValuesLowLevel), &payload).await?.unwrap();
384        Ok(SetLedValuesLowLevel::from_le_byte_slice(result.body()))
385    }
386
387    /// Returns *length* RGB(W) values starting from the
388    /// given *index*.
389    ///
390    /// If the channel mapping has 3 colors, you will get the data in the sequence
391    /// RGBRGBRGB... if the channel mapping has 4 colors you will get the data in the
392    /// sequence RGBWRGBWRGBW...
393    /// (assuming you start at an index divisible by 3 (RGB) or 4 (RGBW)).
394    pub async fn get_led_values_low_level(&mut self, index: u16, length: u16) -> Result<LedValuesLowLevel, TinkerforgeError> {
395        let mut payload = [0; 4];
396        index.write_to_slice(&mut payload[0..2]);
397        length.write_to_slice(&mut payload[2..4]);
398
399        #[allow(unused_variables)]
400        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetLedValuesLowLevel), &payload).await?;
401        Ok(LedValuesLowLevel::from_le_byte_slice(result.body()))
402    }
403
404    /// Sets the frame duration.
405    ///
406    /// Example: If you want to achieve 20 frames per second, you should
407    /// set the frame duration to 50ms (50ms * 20 = 1 second).
408    ///
409    /// For an explanation of the general approach see [`set_led_values`].
410    ///
411    /// Default value: 100ms (10 frames per second).
412    pub async fn set_frame_duration(&mut self, duration: u16) -> Result<(), TinkerforgeError> {
413        let mut payload = [0; 2];
414        duration.write_to_slice(&mut payload[0..2]);
415
416        #[allow(unused_variables)]
417        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetFrameDuration), &payload).await?;
418        Ok(())
419    }
420
421    /// Returns the frame duration as set by [`set_frame_duration`].
422    pub async fn get_frame_duration(&mut self) -> Result<u16, TinkerforgeError> {
423        let payload = [0; 0];
424
425        #[allow(unused_variables)]
426        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetFrameDuration), &payload).await?;
427        Ok(u16::from_le_byte_slice(result.body()))
428    }
429
430    /// Returns the current supply voltage of the LEDs.
431    pub async fn get_supply_voltage(&mut self) -> Result<u16, TinkerforgeError> {
432        let payload = [0; 0];
433
434        #[allow(unused_variables)]
435        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetSupplyVoltage), &payload).await?;
436        Ok(u16::from_le_byte_slice(result.body()))
437    }
438
439    /// Sets the frequency of the clock.
440    ///
441    /// The Bricklet will choose the nearest achievable frequency, which may
442    /// be off by a few Hz. You can get the exact frequency that is used by
443    /// calling [`get_clock_frequency`].
444    ///
445    /// If you have problems with flickering LEDs, they may be bits flipping. You
446    /// can fix this by either making the connection between the LEDs and the
447    /// Bricklet shorter or by reducing the frequency.
448    ///
449    /// With a decreasing frequency your maximum frames per second will decrease
450    /// too.
451    pub async fn set_clock_frequency(&mut self, frequency: u32) -> Result<(), TinkerforgeError> {
452        let mut payload = [0; 4];
453        frequency.write_to_slice(&mut payload[0..4]);
454
455        #[allow(unused_variables)]
456        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetClockFrequency), &payload).await?;
457        Ok(())
458    }
459
460    /// Returns the currently used clock frequency as set by [`set_clock_frequency`].
461    pub async fn get_clock_frequency(&mut self) -> Result<u32, TinkerforgeError> {
462        let payload = [0; 0];
463
464        #[allow(unused_variables)]
465        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetClockFrequency), &payload).await?;
466        Ok(u32::from_le_byte_slice(result.body()))
467    }
468
469    /// Sets the type of the LED driver chip. We currently support the chips
470    ///
471    /// * WS2801,
472    /// * WS2811,
473    /// * WS2812 / SK6812 / NeoPixel RGB,
474    /// * SK6812RGBW / NeoPixel RGBW (Chip Type = WS2812),
475    /// * WS2813 / WS2815 (Chip Type = WS2812)
476    /// * LPD8806 and
477    /// * APA102 / DotStar.
478    ///
479    /// Associated constants:
480    /// * LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2801
481    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2811
482    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2812
483    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_LPD8806
484    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_APA102
485    pub async fn set_chip_type(&mut self, chip: u16) -> Result<(), TinkerforgeError> {
486        let mut payload = [0; 2];
487        chip.write_to_slice(&mut payload[0..2]);
488
489        #[allow(unused_variables)]
490        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetChipType), &payload).await?;
491        Ok(())
492    }
493
494    /// Returns the currently used chip type as set by [`set_chip_type`].
495    ///
496    /// Associated constants:
497    /// * LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2801
498    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2811
499    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_WS2812
500    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_LPD8806
501    ///	* LED_STRIP_V2_BRICKLET_CHIP_TYPE_APA102
502    pub async fn get_chip_type(&mut self) -> Result<u16, TinkerforgeError> {
503        let payload = [0; 0];
504
505        #[allow(unused_variables)]
506        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetChipType), &payload).await?;
507        Ok(u16::from_le_byte_slice(result.body()))
508    }
509
510    /// Sets the channel mapping for the connected LEDs.
511    ///
512    /// If the mapping has 4 colors, the function [`set_led_values`] expects 4
513    /// values per pixel and if the mapping has 3 colors it expects 3 values per pixel.
514    ///
515    /// The function always expects the order RGB(W). The connected LED driver chips
516    /// might have their 3 or 4 channels in a different order. For example, the WS2801
517    /// chips typically use BGR order, then WS2812 chips typically use GRB order and
518    /// the APA102 chips typically use WBGR order.
519    ///
520    /// The APA102 chips are special. They have three 8-bit channels for RGB
521    /// and an additional 5-bit channel for the overall brightness of the RGB LED
522    /// making them 4-channel chips. Internally the brightness channel is the first
523    /// channel, therefore one of the Wxyz channel mappings should be used. Then
524    /// the W channel controls the brightness.
525    ///
526    /// Associated constants:
527    /// * LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGB
528    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBG
529    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRG
530    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGR
531    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRB
532    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBR
533    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGBW
534    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGWB
535    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBGW
536    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBWG
537    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RWGB
538    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RWBG
539    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRWB
540    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRBW
541    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBWR
542    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBRW
543    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GWBR
544    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GWRB
545    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRGW
546    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRWG
547    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGRW
548    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGWR
549    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BWRG
550    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BWGR
551    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WRBG
552    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WRGB
553    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WGBR
554    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WGRB
555    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WBGR
556    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WBRG
557    pub async fn set_channel_mapping(&mut self, mapping: u8) -> Result<(), TinkerforgeError> {
558        let mut payload = [0; 1];
559        mapping.write_to_slice(&mut payload[0..1]);
560
561        #[allow(unused_variables)]
562        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetChannelMapping), &payload).await?;
563        Ok(())
564    }
565
566    /// Returns the currently used channel mapping as set by [`set_channel_mapping`].
567    ///
568    /// Associated constants:
569    /// * LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGB
570    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBG
571    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRG
572    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGR
573    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRB
574    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBR
575    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGBW
576    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RGWB
577    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBGW
578    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RBWG
579    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RWGB
580    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_RWBG
581    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRWB
582    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GRBW
583    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBWR
584    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GBRW
585    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GWBR
586    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_GWRB
587    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRGW
588    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BRWG
589    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGRW
590    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BGWR
591    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BWRG
592    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_BWGR
593    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WRBG
594    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WRGB
595    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WGBR
596    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WGRB
597    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WBGR
598    ///	* LED_STRIP_V2_BRICKLET_CHANNEL_MAPPING_WBRG
599    pub async fn get_channel_mapping(&mut self) -> Result<u8, TinkerforgeError> {
600        let payload = [0; 0];
601
602        #[allow(unused_variables)]
603        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetChannelMapping), &payload).await?;
604        Ok(u8::from_le_byte_slice(result.body()))
605    }
606
607    /// Enables/disables the [`get_frame_started_callback_receiver`] receiver.
608    pub async fn set_frame_started_callback_configuration(&mut self, enable: bool) -> Result<(), TinkerforgeError> {
609        let mut payload = [0; 1];
610        enable.write_to_slice(&mut payload[0..1]);
611
612        #[allow(unused_variables)]
613        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetFrameStartedCallbackConfiguration), &payload).await?;
614        Ok(())
615    }
616
617    /// Returns the configuration as set by
618    /// [`set_frame_started_callback_configuration`].
619    pub async fn get_frame_started_callback_configuration(&mut self) -> Result<bool, TinkerforgeError> {
620        let payload = [0; 0];
621
622        #[allow(unused_variables)]
623        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetFrameStartedCallbackConfiguration), &payload).await?;
624        Ok(bool::from_le_byte_slice(result.body()))
625    }
626
627    /// Returns the error count for the communication between Brick and Bricklet.
628    ///
629    /// The errors are divided into
630    ///
631    /// * ACK checksum errors,
632    /// * message checksum errors,
633    /// * framing errors and
634    /// * overflow errors.
635    ///
636    /// The errors counts are for errors that occur on the Bricklet side. All
637    /// Bricks have a similar function that returns the errors on the Brick side.
638    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
639        let payload = [0; 0];
640
641        #[allow(unused_variables)]
642        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetSpitfpErrorCount), &payload).await?;
643        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
644    }
645
646    /// Sets the bootloader mode and returns the status after the requested
647    /// mode change was instigated.
648    ///
649    /// You can change from bootloader mode to firmware mode and vice versa. A change
650    /// from bootloader mode to firmware mode will only take place if the entry function,
651    /// device identifier and CRC are present and correct.
652    ///
653    /// This function is used by Brick Viewer during flashing. It should not be
654    /// necessary to call it in a normal user program.
655    ///
656    /// Associated constants:
657    /// * LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
658    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
659    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
660    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
661    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
662    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_OK
663    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
664    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
665    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
666    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
667    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
668    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
669        let mut payload = [0; 1];
670        mode.write_to_slice(&mut payload[0..1]);
671
672        #[allow(unused_variables)]
673        let result = self.device.get(u8::from(LedStripV2BrickletFunction::SetBootloaderMode), &payload).await?;
674        Ok(u8::from_le_byte_slice(result.body()))
675    }
676
677    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
678    ///
679    /// Associated constants:
680    /// * LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
681    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
682    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
683    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
684    ///	* LED_STRIP_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
685    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
686        let payload = [0; 0];
687
688        #[allow(unused_variables)]
689        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetBootloaderMode), &payload).await?;
690        Ok(u8::from_le_byte_slice(result.body()))
691    }
692
693    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
694    /// to be increased by chunks of size 64. The data is written to flash
695    /// every 4 chunks (which equals to one page of size 256).
696    ///
697    /// This function is used by Brick Viewer during flashing. It should not be
698    /// necessary to call it in a normal user program.
699    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
700        let mut payload = [0; 4];
701        pointer.write_to_slice(&mut payload[0..4]);
702
703        #[allow(unused_variables)]
704        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetWriteFirmwarePointer), &payload).await?;
705        Ok(())
706    }
707
708    /// Writes 64 Bytes of firmware at the position as written by
709    /// [`set_write_firmware_pointer`] before. The firmware is written
710    /// to flash every 4 chunks.
711    ///
712    /// You can only write firmware in bootloader mode.
713    ///
714    /// This function is used by Brick Viewer during flashing. It should not be
715    /// necessary to call it in a normal user program.
716    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
717        let mut payload = [0; 64];
718        data.write_to_slice(&mut payload[0..64]);
719
720        #[allow(unused_variables)]
721        let result = self.device.get(u8::from(LedStripV2BrickletFunction::WriteFirmware), &payload).await?;
722        Ok(u8::from_le_byte_slice(result.body()))
723    }
724
725    /// Sets the status LED configuration. By default the LED shows
726    /// communication traffic between Brick and Bricklet, it flickers once
727    /// for every 10 received data packets.
728    ///
729    /// You can also turn the LED permanently on/off or show a heartbeat.
730    ///
731    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
732    ///
733    /// Associated constants:
734    /// * LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_OFF
735    ///	* LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_ON
736    ///	* LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
737    ///	* LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
738    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
739        let mut payload = [0; 1];
740        config.write_to_slice(&mut payload[0..1]);
741
742        #[allow(unused_variables)]
743        let result = self.device.set(u8::from(LedStripV2BrickletFunction::SetStatusLedConfig), &payload).await?;
744        Ok(())
745    }
746
747    /// Returns the configuration as set by [`set_status_led_config`]
748    ///
749    /// Associated constants:
750    /// * LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_OFF
751    ///	* LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_ON
752    ///	* LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
753    ///	* LED_STRIP_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
754    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
755        let payload = [0; 0];
756
757        #[allow(unused_variables)]
758        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetStatusLedConfig), &payload).await?;
759        Ok(u8::from_le_byte_slice(result.body()))
760    }
761
762    /// Returns the temperature as measured inside the microcontroller. The
763    /// value returned is not the ambient temperature!
764    ///
765    /// The temperature is only proportional to the real temperature and it has bad
766    /// accuracy. Practically it is only useful as an indicator for
767    /// temperature changes.
768    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
769        let payload = [0; 0];
770
771        #[allow(unused_variables)]
772        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetChipTemperature), &payload).await?;
773        Ok(i16::from_le_byte_slice(result.body()))
774    }
775
776    /// Calling this function will reset the Bricklet. All configurations
777    /// will be lost.
778    ///
779    /// After a reset you have to create new device objects,
780    /// calling functions on the existing ones will result in
781    /// undefined behavior!
782    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
783        let payload = [0; 0];
784
785        #[allow(unused_variables)]
786        let result = self.device.set(u8::from(LedStripV2BrickletFunction::Reset), &payload).await?;
787        Ok(())
788    }
789
790    /// Writes a new UID into flash. If you want to set a new UID
791    /// you have to decode the Base58 encoded UID string into an
792    /// integer first.
793    ///
794    /// We recommend that you use Brick Viewer to change the UID.
795    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
796        let mut payload = [0; 4];
797        uid.write_to_slice(&mut payload[0..4]);
798
799        #[allow(unused_variables)]
800        let result = self.device.set(u8::from(LedStripV2BrickletFunction::WriteUid), &payload).await?;
801        Ok(())
802    }
803
804    /// Returns the current UID as an integer. Encode as
805    /// Base58 to get the usual string version.
806    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
807        let payload = [0; 0];
808
809        #[allow(unused_variables)]
810        let result = self.device.get(u8::from(LedStripV2BrickletFunction::ReadUid), &payload).await?;
811        Ok(u32::from_le_byte_slice(result.body()))
812    }
813
814    /// Returns the UID, the UID where the Bricklet is connected to,
815    /// the position, the hardware and firmware version as well as the
816    /// device identifier.
817    ///
818    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
819    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
820    /// position 'z'.
821    ///
822    /// The device identifier numbers can be found [here](device_identifier).
823    /// |device_identifier_constant|
824    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
825        let payload = [0; 0];
826
827        #[allow(unused_variables)]
828        let result = self.device.get(u8::from(LedStripV2BrickletFunction::GetIdentity), &payload).await?;
829        Ok(Identity::from_le_byte_slice(result.body()))
830    }
831}