tinkerforge_async/bindings/
dmx_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//! DMX master and slave.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/DMX_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, converting_high_level_callback_receiver::ConvertingHighLevelCallbackReceiver,
17    converting_receiver::BrickletRecvTimeoutError, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
18    low_level_traits::LowLevelRead,
19};
20#[allow(unused_imports)]
21use futures_core::Stream;
22#[allow(unused_imports)]
23use tokio_stream::StreamExt;
24pub enum DmxBrickletFunction {
25    SetDmxMode,
26    GetDmxMode,
27    WriteFrameLowLevel,
28    ReadFrameLowLevel,
29    SetFrameDuration,
30    GetFrameDuration,
31    GetFrameErrorCount,
32    SetCommunicationLedConfig,
33    GetCommunicationLedConfig,
34    SetErrorLedConfig,
35    GetErrorLedConfig,
36    SetFrameCallbackConfig,
37    GetFrameCallbackConfig,
38    GetSpitfpErrorCount,
39    SetBootloaderMode,
40    GetBootloaderMode,
41    SetWriteFirmwarePointer,
42    WriteFirmware,
43    SetStatusLedConfig,
44    GetStatusLedConfig,
45    GetChipTemperature,
46    Reset,
47    WriteUid,
48    ReadUid,
49    GetIdentity,
50    CallbackFrameStarted,
51    CallbackFrameAvailable,
52    CallbackFrameLowLevel,
53    CallbackFrameErrorCount,
54}
55impl From<DmxBrickletFunction> for u8 {
56    fn from(fun: DmxBrickletFunction) -> Self {
57        match fun {
58            DmxBrickletFunction::SetDmxMode => 1,
59            DmxBrickletFunction::GetDmxMode => 2,
60            DmxBrickletFunction::WriteFrameLowLevel => 3,
61            DmxBrickletFunction::ReadFrameLowLevel => 4,
62            DmxBrickletFunction::SetFrameDuration => 5,
63            DmxBrickletFunction::GetFrameDuration => 6,
64            DmxBrickletFunction::GetFrameErrorCount => 7,
65            DmxBrickletFunction::SetCommunicationLedConfig => 8,
66            DmxBrickletFunction::GetCommunicationLedConfig => 9,
67            DmxBrickletFunction::SetErrorLedConfig => 10,
68            DmxBrickletFunction::GetErrorLedConfig => 11,
69            DmxBrickletFunction::SetFrameCallbackConfig => 12,
70            DmxBrickletFunction::GetFrameCallbackConfig => 13,
71            DmxBrickletFunction::GetSpitfpErrorCount => 234,
72            DmxBrickletFunction::SetBootloaderMode => 235,
73            DmxBrickletFunction::GetBootloaderMode => 236,
74            DmxBrickletFunction::SetWriteFirmwarePointer => 237,
75            DmxBrickletFunction::WriteFirmware => 238,
76            DmxBrickletFunction::SetStatusLedConfig => 239,
77            DmxBrickletFunction::GetStatusLedConfig => 240,
78            DmxBrickletFunction::GetChipTemperature => 242,
79            DmxBrickletFunction::Reset => 243,
80            DmxBrickletFunction::WriteUid => 248,
81            DmxBrickletFunction::ReadUid => 249,
82            DmxBrickletFunction::GetIdentity => 255,
83            DmxBrickletFunction::CallbackFrameStarted => 14,
84            DmxBrickletFunction::CallbackFrameAvailable => 15,
85            DmxBrickletFunction::CallbackFrameLowLevel => 16,
86            DmxBrickletFunction::CallbackFrameErrorCount => 17,
87        }
88    }
89}
90pub const DMX_BRICKLET_DMX_MODE_MASTER: u8 = 0;
91pub const DMX_BRICKLET_DMX_MODE_SLAVE: u8 = 1;
92pub const DMX_BRICKLET_COMMUNICATION_LED_CONFIG_OFF: u8 = 0;
93pub const DMX_BRICKLET_COMMUNICATION_LED_CONFIG_ON: u8 = 1;
94pub const DMX_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
95pub const DMX_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION: u8 = 3;
96pub const DMX_BRICKLET_ERROR_LED_CONFIG_OFF: u8 = 0;
97pub const DMX_BRICKLET_ERROR_LED_CONFIG_ON: u8 = 1;
98pub const DMX_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
99pub const DMX_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR: u8 = 3;
100pub const DMX_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
101pub const DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
102pub const DMX_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
103pub const DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
104pub const DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
105pub const DMX_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
106pub const DMX_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
107pub const DMX_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
108pub const DMX_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
109pub const DMX_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
110pub const DMX_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
111pub const DMX_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
112pub const DMX_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
113pub const DMX_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
114pub const DMX_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
115
116#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
117pub struct WriteFrameLowLevel {}
118impl FromByteSlice for WriteFrameLowLevel {
119    fn bytes_expected() -> usize {
120        0
121    }
122    fn from_le_byte_slice(_bytes: &[u8]) -> WriteFrameLowLevel {
123        WriteFrameLowLevel {}
124    }
125}
126
127#[derive(Clone, Copy)]
128pub struct ReadFrameLowLevel {
129    pub frame_length: u16,
130    pub frame_chunk_offset: u16,
131    pub frame_chunk_data: [u8; 56],
132    pub frame_number: u32,
133}
134impl FromByteSlice for ReadFrameLowLevel {
135    fn bytes_expected() -> usize {
136        64
137    }
138    fn from_le_byte_slice(bytes: &[u8]) -> ReadFrameLowLevel {
139        ReadFrameLowLevel {
140            frame_length: <u16>::from_le_byte_slice(&bytes[0..2]),
141            frame_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
142            frame_chunk_data: <[u8; 56]>::from_le_byte_slice(&bytes[4..60]),
143            frame_number: <u32>::from_le_byte_slice(&bytes[60..64]),
144        }
145    }
146}
147impl LowLevelRead<u8, ReadFrameResult> for ReadFrameLowLevel {
148    fn ll_message_length(&self) -> usize {
149        self.frame_length as usize
150    }
151
152    fn ll_message_chunk_offset(&self) -> usize {
153        self.frame_chunk_offset as usize
154    }
155
156    fn ll_message_chunk_data(&self) -> &[u8] {
157        &self.frame_chunk_data
158    }
159
160    fn get_result(&self) -> ReadFrameResult {
161        ReadFrameResult { frame_number: self.frame_number }
162    }
163}
164
165#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
166pub struct FrameErrorCount {
167    pub overrun_error_count: u32,
168    pub framing_error_count: u32,
169}
170impl FromByteSlice for FrameErrorCount {
171    fn bytes_expected() -> usize {
172        8
173    }
174    fn from_le_byte_slice(bytes: &[u8]) -> FrameErrorCount {
175        FrameErrorCount {
176            overrun_error_count: <u32>::from_le_byte_slice(&bytes[0..4]),
177            framing_error_count: <u32>::from_le_byte_slice(&bytes[4..8]),
178        }
179    }
180}
181
182#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
183pub struct FrameCallbackConfig {
184    pub frame_started_callback_enabled: bool,
185    pub frame_available_callback_enabled: bool,
186    pub frame_callback_enabled: bool,
187    pub frame_error_count_callback_enabled: bool,
188}
189impl FromByteSlice for FrameCallbackConfig {
190    fn bytes_expected() -> usize {
191        4
192    }
193    fn from_le_byte_slice(bytes: &[u8]) -> FrameCallbackConfig {
194        FrameCallbackConfig {
195            frame_started_callback_enabled: <bool>::from_le_byte_slice(&bytes[0..1]),
196            frame_available_callback_enabled: <bool>::from_le_byte_slice(&bytes[1..2]),
197            frame_callback_enabled: <bool>::from_le_byte_slice(&bytes[2..3]),
198            frame_error_count_callback_enabled: <bool>::from_le_byte_slice(&bytes[3..4]),
199        }
200    }
201}
202
203#[derive(Clone, Copy)]
204pub struct FrameLowLevelEvent {
205    pub frame_length: u16,
206    pub frame_chunk_offset: u16,
207    pub frame_chunk_data: [u8; 56],
208    pub frame_number: u32,
209}
210impl FromByteSlice for FrameLowLevelEvent {
211    fn bytes_expected() -> usize {
212        64
213    }
214    fn from_le_byte_slice(bytes: &[u8]) -> FrameLowLevelEvent {
215        FrameLowLevelEvent {
216            frame_length: <u16>::from_le_byte_slice(&bytes[0..2]),
217            frame_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
218            frame_chunk_data: <[u8; 56]>::from_le_byte_slice(&bytes[4..60]),
219            frame_number: <u32>::from_le_byte_slice(&bytes[60..64]),
220        }
221    }
222}
223impl LowLevelRead<u8, FrameResult> for FrameLowLevelEvent {
224    fn ll_message_length(&self) -> usize {
225        self.frame_length as usize
226    }
227
228    fn ll_message_chunk_offset(&self) -> usize {
229        self.frame_chunk_offset as usize
230    }
231
232    fn ll_message_chunk_data(&self) -> &[u8] {
233        &self.frame_chunk_data
234    }
235
236    fn get_result(&self) -> FrameResult {
237        FrameResult { frame_number: self.frame_number }
238    }
239}
240
241#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
242pub struct FrameErrorCountEvent {
243    pub overrun_error_count: u32,
244    pub framing_error_count: u32,
245}
246impl FromByteSlice for FrameErrorCountEvent {
247    fn bytes_expected() -> usize {
248        8
249    }
250    fn from_le_byte_slice(bytes: &[u8]) -> FrameErrorCountEvent {
251        FrameErrorCountEvent {
252            overrun_error_count: <u32>::from_le_byte_slice(&bytes[0..4]),
253            framing_error_count: <u32>::from_le_byte_slice(&bytes[4..8]),
254        }
255    }
256}
257
258#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
259pub struct SpitfpErrorCount {
260    pub error_count_ack_checksum: u32,
261    pub error_count_message_checksum: u32,
262    pub error_count_frame: u32,
263    pub error_count_overflow: u32,
264}
265impl FromByteSlice for SpitfpErrorCount {
266    fn bytes_expected() -> usize {
267        16
268    }
269    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
270        SpitfpErrorCount {
271            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
272            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
273            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
274            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
275        }
276    }
277}
278
279#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
280pub struct Identity {
281    pub uid: String,
282    pub connected_uid: String,
283    pub position: char,
284    pub hardware_version: [u8; 3],
285    pub firmware_version: [u8; 3],
286    pub device_identifier: u16,
287}
288impl FromByteSlice for Identity {
289    fn bytes_expected() -> usize {
290        25
291    }
292    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
293        Identity {
294            uid: <String>::from_le_byte_slice(&bytes[0..8]),
295            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
296            position: <char>::from_le_byte_slice(&bytes[16..17]),
297            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
298            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
299            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
300        }
301    }
302}
303
304#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
305pub struct WriteFrameResult {}
306
307#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
308pub struct ReadFrameResult {
309    pub frame_number: u32,
310}
311
312#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
313pub struct FrameResult {
314    pub frame_number: u32,
315}
316
317/// DMX master and slave
318#[derive(Clone)]
319pub struct DmxBricklet {
320    device: Device,
321}
322impl DmxBricklet {
323    pub const DEVICE_IDENTIFIER: u16 = 285;
324    pub const DEVICE_DISPLAY_NAME: &'static str = "DMX Bricklet";
325    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
326    pub fn new(uid: Uid, connection: AsyncIpConnection) -> DmxBricklet {
327        let mut result = DmxBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
328        result.device.response_expected[u8::from(DmxBrickletFunction::SetDmxMode) as usize] = ResponseExpectedFlag::False;
329        result.device.response_expected[u8::from(DmxBrickletFunction::GetDmxMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
330        result.device.response_expected[u8::from(DmxBrickletFunction::WriteFrameLowLevel) as usize] = ResponseExpectedFlag::True;
331        result.device.response_expected[u8::from(DmxBrickletFunction::ReadFrameLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
332        result.device.response_expected[u8::from(DmxBrickletFunction::SetFrameDuration) as usize] = ResponseExpectedFlag::False;
333        result.device.response_expected[u8::from(DmxBrickletFunction::GetFrameDuration) as usize] = ResponseExpectedFlag::AlwaysTrue;
334        result.device.response_expected[u8::from(DmxBrickletFunction::GetFrameErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
335        result.device.response_expected[u8::from(DmxBrickletFunction::SetCommunicationLedConfig) as usize] = ResponseExpectedFlag::False;
336        result.device.response_expected[u8::from(DmxBrickletFunction::GetCommunicationLedConfig) as usize] =
337            ResponseExpectedFlag::AlwaysTrue;
338        result.device.response_expected[u8::from(DmxBrickletFunction::SetErrorLedConfig) as usize] = ResponseExpectedFlag::False;
339        result.device.response_expected[u8::from(DmxBrickletFunction::GetErrorLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
340        result.device.response_expected[u8::from(DmxBrickletFunction::SetFrameCallbackConfig) as usize] = ResponseExpectedFlag::True;
341        result.device.response_expected[u8::from(DmxBrickletFunction::GetFrameCallbackConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
342        result.device.response_expected[u8::from(DmxBrickletFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
343        result.device.response_expected[u8::from(DmxBrickletFunction::SetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
344        result.device.response_expected[u8::from(DmxBrickletFunction::GetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
345        result.device.response_expected[u8::from(DmxBrickletFunction::SetWriteFirmwarePointer) as usize] = ResponseExpectedFlag::False;
346        result.device.response_expected[u8::from(DmxBrickletFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
347        result.device.response_expected[u8::from(DmxBrickletFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
348        result.device.response_expected[u8::from(DmxBrickletFunction::GetStatusLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
349        result.device.response_expected[u8::from(DmxBrickletFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
350        result.device.response_expected[u8::from(DmxBrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
351        result.device.response_expected[u8::from(DmxBrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
352        result.device.response_expected[u8::from(DmxBrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
353        result.device.response_expected[u8::from(DmxBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
354        result
355    }
356
357    /// Returns the response expected flag for the function specified by the function ID parameter.
358    /// It is true if the function is expected to send a response, false otherwise.
359    ///
360    /// For getter functions this is enabled by default and cannot be disabled, because those
361    /// functions will always send a response. For callback configuration functions it is enabled
362    /// by default too, but can be disabled by [`set_response_expected`](crate::dmx_bricklet::DmxBricklet::set_response_expected).
363    /// For setter functions it is disabled by default and can be enabled.
364    ///
365    /// Enabling the response expected flag for a setter function allows to detect timeouts
366    /// and other error conditions calls of this setter as well. The device will then send a response
367    /// for this purpose. If this flag is disabled for a setter function then no response is sent
368    /// and errors are silently ignored, because they cannot be detected.
369    ///
370    /// See [`set_response_expected`](crate::dmx_bricklet::DmxBricklet::set_response_expected) for the list of function ID constants available for this function.
371    pub fn get_response_expected(&mut self, fun: DmxBrickletFunction) -> Result<bool, GetResponseExpectedError> {
372        self.device.get_response_expected(u8::from(fun))
373    }
374
375    /// Changes the response expected flag of the function specified by the function ID parameter.
376    /// This flag can only be changed for setter (default value: false) and callback configuration
377    /// functions (default value: true). For getter functions it is always enabled.
378    ///
379    /// Enabling the response expected flag for a setter function allows to detect timeouts and
380    /// other error conditions calls of this setter as well. The device will then send a response
381    /// for this purpose. If this flag is disabled for a setter function then no response is sent
382    /// and errors are silently ignored, because they cannot be detected.
383    pub fn set_response_expected(&mut self, fun: DmxBrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
384        self.device.set_response_expected(u8::from(fun), response_expected)
385    }
386
387    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
388    pub fn set_response_expected_all(&mut self, response_expected: bool) {
389        self.device.set_response_expected_all(response_expected)
390    }
391
392    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
393    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
394    pub fn get_api_version(&self) -> [u8; 3] {
395        self.device.api_version
396    }
397
398    /// This receiver is triggered as soon as a new frame write is started.
399    /// You should send the data for the next frame directly after this receiver
400    /// was triggered.
401    ///
402    /// For an explanation of the general approach see [`write_frame`].
403    ///
404    /// This receiver can be enabled via [`set_frame_callback_config`].
405    ///
406    /// This receiver can only be triggered in master mode.
407    ///
408    /// [`write_frame`]: #method.write_frame
409    /// [`set_frame_callback_config`]: #method.set_frame_callback_config
410    pub async fn get_frame_started_callback_receiver(&mut self) -> impl Stream<Item = ()> {
411        self.device.get_callback_receiver(u8::from(DmxBrickletFunction::CallbackFrameStarted)).await.map(|_p| ())
412    }
413
414    /// This receiver is triggered in slave mode when a new frame was received from the DMX master
415    /// and it can be read out. You have to read the frame before the master has written
416    /// the next frame, see [`read_frame`] for more details.
417    ///
418    /// The parameter is the frame number, it is increased by one with each received frame.
419    ///
420    /// This receiver can be enabled via [`set_frame_callback_config`].
421    ///
422    /// This receiver can only be triggered in slave mode.
423    pub async fn get_frame_available_callback_receiver(&mut self) -> impl Stream<Item = u32> {
424        self.device
425            .get_callback_receiver(u8::from(DmxBrickletFunction::CallbackFrameAvailable))
426            .await
427            .map(|p| u32::from_le_byte_slice(p.body()))
428    }
429
430    /// See [`get_frame_callback_receiver`](crate::dmx::DMX::get_frame_callback_receiver)
431    pub async fn get_frame_low_level_callback_receiver(&mut self) -> impl Stream<Item = FrameLowLevelEvent> {
432        self.device
433            .get_callback_receiver(u8::from(DmxBrickletFunction::CallbackFrameLowLevel))
434            .await
435            .map(|p| FrameLowLevelEvent::from_le_byte_slice(p.body()))
436    }
437
438    /// This receiver is called if a new error occurs. It returns
439    /// the current overrun and framing error count.
440    pub async fn get_frame_error_count_callback_receiver(&mut self) -> impl Stream<Item = FrameErrorCountEvent> {
441        self.device
442            .get_callback_receiver(u8::from(DmxBrickletFunction::CallbackFrameErrorCount))
443            .await
444            .map(|p| FrameErrorCountEvent::from_le_byte_slice(p.body()))
445    }
446
447    /// Sets the DMX mode to either master or slave.
448    ///
449    /// Calling this function sets frame number to 0.
450    ///
451    /// Associated constants:
452    /// * DMX_BRICKLET_DMX_MODE_MASTER
453    ///	* DMX_BRICKLET_DMX_MODE_SLAVE
454    pub async fn set_dmx_mode(&mut self, dmx_mode: u8) -> Result<(), TinkerforgeError> {
455        let mut payload = [0; 1];
456        dmx_mode.write_to_slice(&mut payload[0..1]);
457
458        #[allow(unused_variables)]
459        let result = self.device.set(u8::from(DmxBrickletFunction::SetDmxMode), &payload).await?;
460        Ok(())
461    }
462
463    /// Returns the DMX mode, as set by [`set_dmx_mode`].
464    ///
465    /// Associated constants:
466    /// * DMX_BRICKLET_DMX_MODE_MASTER
467    ///	* DMX_BRICKLET_DMX_MODE_SLAVE
468    pub async fn get_dmx_mode(&mut self) -> Result<u8, TinkerforgeError> {
469        let payload = [0; 0];
470
471        #[allow(unused_variables)]
472        let result = self.device.get(u8::from(DmxBrickletFunction::GetDmxMode), &payload).await?;
473        Ok(u8::from_le_byte_slice(result.body()))
474    }
475
476    /// Writes a DMX frame. The maximum frame size is 512 byte. Each byte represents one channel.
477    ///
478    /// The next frame can be written after the [`get_frame_started_callback_receiver`] receiver was called. The frame
479    /// is double buffered, so a new frame can be written as soon as the writing of the prior frame
480    /// starts.
481    ///
482    /// The data will be transfered when the next frame duration ends, see [`set_frame_duration`].
483    ///
484    /// Generic approach:
485    ///
486    /// * Set the frame duration to a value that represents the number of frames per second you want to achieve.
487    /// * Set channels for first frame.
488    /// * Wait for the [`get_frame_started_callback_receiver`] receiver.
489    /// * Set channels for next frame.
490    /// * Wait for the [`get_frame_started_callback_receiver`] receiver.
491    /// * and so on.
492    ///
493    /// This approach ensures that you can set new DMX data with a fixed frame rate.
494    ///
495    /// This function can only be called in master mode.
496    pub async fn write_frame_low_level(
497        &mut self,
498        frame_length: u16,
499        frame_chunk_offset: u16,
500        frame_chunk_data: &[u8; 60],
501    ) -> Result<WriteFrameLowLevel, TinkerforgeError> {
502        let mut payload = [0; 64];
503        frame_length.write_to_slice(&mut payload[0..2]);
504        frame_chunk_offset.write_to_slice(&mut payload[2..4]);
505        frame_chunk_data.write_to_slice(&mut payload[4..64]);
506
507        #[allow(unused_variables)]
508        let result = self.device.set(u8::from(DmxBrickletFunction::WriteFrameLowLevel), &payload).await?.unwrap();
509        Ok(WriteFrameLowLevel::from_le_byte_slice(result.body()))
510    }
511
512    /// Returns the last frame that was written by the DMX master. The size of the array
513    /// is equivalent to the number of channels in the frame. Each byte represents one channel.
514    ///
515    /// The next frame is available after the [`get_frame_available_callback_receiver`] receiver was called.
516    ///
517    /// Generic approach:
518    ///
519    /// * Call [`read_frame`] to get first frame.
520    /// * Wait for the [`get_frame_available_callback_receiver`] receiver.
521    /// * Call [`read_frame`] to get second frame.
522    /// * Wait for the [`get_frame_available_callback_receiver`] receiver.
523    /// * and so on.
524    ///
525    /// Instead of polling this function you can also use the [`get_frame_callback_receiver`] receiver.
526    /// You can enable it with [`set_frame_callback_config`].
527    ///
528    /// The frame number starts at 0 and it is increased by one with each received frame.
529    ///
530    /// This function can only be called in slave mode.
531    pub async fn read_frame_low_level(&mut self) -> Result<ReadFrameLowLevel, TinkerforgeError> {
532        let payload = [0; 0];
533
534        #[allow(unused_variables)]
535        let result = self.device.get(u8::from(DmxBrickletFunction::ReadFrameLowLevel), &payload).await?;
536        Ok(ReadFrameLowLevel::from_le_byte_slice(result.body()))
537    }
538
539    /// Sets the duration of a frame.
540    ///
541    /// Example: If you want to achieve 20 frames per second, you should
542    /// set the frame duration to 50ms (50ms * 20 = 1 second).
543    ///
544    /// If you always want to send a frame as fast as possible you can set
545    /// this value to 0.
546    ///
547    /// This setting is only used in master mode.
548    pub async fn set_frame_duration(&mut self, frame_duration: u16) -> Result<(), TinkerforgeError> {
549        let mut payload = [0; 2];
550        frame_duration.write_to_slice(&mut payload[0..2]);
551
552        #[allow(unused_variables)]
553        let result = self.device.set(u8::from(DmxBrickletFunction::SetFrameDuration), &payload).await?;
554        Ok(())
555    }
556
557    /// Returns the frame duration as set by [`set_frame_duration`].
558    pub async fn get_frame_duration(&mut self) -> Result<u16, TinkerforgeError> {
559        let payload = [0; 0];
560
561        #[allow(unused_variables)]
562        let result = self.device.get(u8::from(DmxBrickletFunction::GetFrameDuration), &payload).await?;
563        Ok(u16::from_le_byte_slice(result.body()))
564    }
565
566    /// Returns the current number of overrun and framing errors.
567    pub async fn get_frame_error_count(&mut self) -> Result<FrameErrorCount, TinkerforgeError> {
568        let payload = [0; 0];
569
570        #[allow(unused_variables)]
571        let result = self.device.get(u8::from(DmxBrickletFunction::GetFrameErrorCount), &payload).await?;
572        Ok(FrameErrorCount::from_le_byte_slice(result.body()))
573    }
574
575    /// Sets the communication LED configuration. By default the LED shows
576    /// communication traffic, it flickers once for every 10 received data packets.
577    ///
578    /// You can also turn the LED permanently on/off or show a heartbeat.
579    ///
580    /// If the Bricklet is in bootloader mode, the LED is off.
581    ///
582    /// Associated constants:
583    /// * DMX_BRICKLET_COMMUNICATION_LED_CONFIG_OFF
584    ///	* DMX_BRICKLET_COMMUNICATION_LED_CONFIG_ON
585    ///	* DMX_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT
586    ///	* DMX_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION
587    pub async fn set_communication_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
588        let mut payload = [0; 1];
589        config.write_to_slice(&mut payload[0..1]);
590
591        #[allow(unused_variables)]
592        let result = self.device.set(u8::from(DmxBrickletFunction::SetCommunicationLedConfig), &payload).await?;
593        Ok(())
594    }
595
596    /// Returns the configuration as set by [`set_communication_led_config`]
597    ///
598    /// Associated constants:
599    /// * DMX_BRICKLET_COMMUNICATION_LED_CONFIG_OFF
600    ///	* DMX_BRICKLET_COMMUNICATION_LED_CONFIG_ON
601    ///	* DMX_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT
602    ///	* DMX_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION
603    pub async fn get_communication_led_config(&mut self) -> Result<u8, TinkerforgeError> {
604        let payload = [0; 0];
605
606        #[allow(unused_variables)]
607        let result = self.device.get(u8::from(DmxBrickletFunction::GetCommunicationLedConfig), &payload).await?;
608        Ok(u8::from_le_byte_slice(result.body()))
609    }
610
611    /// Sets the error LED configuration.
612    ///
613    /// By default the error LED turns on if there is any error (see [`get_frame_error_count_callback_receiver`]
614    /// callback). If you call this function with the Show-Error option again, the LED
615    /// will turn off until the next error occurs.
616    ///
617    /// You can also turn the LED permanently on/off or show a heartbeat.
618    ///
619    /// If the Bricklet is in bootloader mode, the LED is off.
620    ///
621    /// Associated constants:
622    /// * DMX_BRICKLET_ERROR_LED_CONFIG_OFF
623    ///	* DMX_BRICKLET_ERROR_LED_CONFIG_ON
624    ///	* DMX_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT
625    ///	* DMX_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR
626    pub async fn set_error_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
627        let mut payload = [0; 1];
628        config.write_to_slice(&mut payload[0..1]);
629
630        #[allow(unused_variables)]
631        let result = self.device.set(u8::from(DmxBrickletFunction::SetErrorLedConfig), &payload).await?;
632        Ok(())
633    }
634
635    /// Returns the configuration as set by [`set_error_led_config`].
636    ///
637    /// Associated constants:
638    /// * DMX_BRICKLET_ERROR_LED_CONFIG_OFF
639    ///	* DMX_BRICKLET_ERROR_LED_CONFIG_ON
640    ///	* DMX_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT
641    ///	* DMX_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR
642    pub async fn get_error_led_config(&mut self) -> Result<u8, TinkerforgeError> {
643        let payload = [0; 0];
644
645        #[allow(unused_variables)]
646        let result = self.device.get(u8::from(DmxBrickletFunction::GetErrorLedConfig), &payload).await?;
647        Ok(u8::from_le_byte_slice(result.body()))
648    }
649
650    /// Enables/Disables the different receivers. By default the
651    /// [`get_frame_started_callback_receiver`] receiver and [`get_frame_available_callback_receiver`] receiver are enabled while
652    /// the [`get_frame_callback_receiver`] receiver and [`get_frame_error_count_callback_receiver`] receiver are disabled.
653    ///
654    /// If you want to use the [`get_frame_callback_receiver`] receiver you can enable it and disable
655    /// the [`get_frame_available_callback_receiver`] receiver at the same time. It becomes redundant in
656    /// this case.
657    pub async fn set_frame_callback_config(
658        &mut self,
659        frame_started_callback_enabled: bool,
660        frame_available_callback_enabled: bool,
661        frame_callback_enabled: bool,
662        frame_error_count_callback_enabled: bool,
663    ) -> Result<(), TinkerforgeError> {
664        let mut payload = [0; 4];
665        frame_started_callback_enabled.write_to_slice(&mut payload[0..1]);
666        frame_available_callback_enabled.write_to_slice(&mut payload[1..2]);
667        frame_callback_enabled.write_to_slice(&mut payload[2..3]);
668        frame_error_count_callback_enabled.write_to_slice(&mut payload[3..4]);
669
670        #[allow(unused_variables)]
671        let result = self.device.set(u8::from(DmxBrickletFunction::SetFrameCallbackConfig), &payload).await?;
672        Ok(())
673    }
674
675    /// Returns the frame receiver config as set by [`set_frame_callback_config`].
676    pub async fn get_frame_callback_config(&mut self) -> Result<FrameCallbackConfig, TinkerforgeError> {
677        let payload = [0; 0];
678
679        #[allow(unused_variables)]
680        let result = self.device.get(u8::from(DmxBrickletFunction::GetFrameCallbackConfig), &payload).await?;
681        Ok(FrameCallbackConfig::from_le_byte_slice(result.body()))
682    }
683
684    /// Returns the error count for the communication between Brick and Bricklet.
685    ///
686    /// The errors are divided into
687    ///
688    /// * ACK checksum errors,
689    /// * message checksum errors,
690    /// * framing errors and
691    /// * overflow errors.
692    ///
693    /// The errors counts are for errors that occur on the Bricklet side. All
694    /// Bricks have a similar function that returns the errors on the Brick side.
695    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
696        let payload = [0; 0];
697
698        #[allow(unused_variables)]
699        let result = self.device.get(u8::from(DmxBrickletFunction::GetSpitfpErrorCount), &payload).await?;
700        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
701    }
702
703    /// Sets the bootloader mode and returns the status after the requested
704    /// mode change was instigated.
705    ///
706    /// You can change from bootloader mode to firmware mode and vice versa. A change
707    /// from bootloader mode to firmware mode will only take place if the entry function,
708    /// device identifier and CRC are present and correct.
709    ///
710    /// This function is used by Brick Viewer during flashing. It should not be
711    /// necessary to call it in a normal user program.
712    ///
713    /// Associated constants:
714    /// * DMX_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
715    ///	* DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE
716    ///	* DMX_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
717    ///	* DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
718    ///	* DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
719    ///	* DMX_BRICKLET_BOOTLOADER_STATUS_OK
720    ///	* DMX_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
721    ///	* DMX_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
722    ///	* DMX_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
723    ///	* DMX_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
724    ///	* DMX_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
725    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
726        let mut payload = [0; 1];
727        mode.write_to_slice(&mut payload[0..1]);
728
729        #[allow(unused_variables)]
730        let result = self.device.get(u8::from(DmxBrickletFunction::SetBootloaderMode), &payload).await?;
731        Ok(u8::from_le_byte_slice(result.body()))
732    }
733
734    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
735    ///
736    /// Associated constants:
737    /// * DMX_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
738    ///	* DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE
739    ///	* DMX_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
740    ///	* DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
741    ///	* DMX_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
742    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
743        let payload = [0; 0];
744
745        #[allow(unused_variables)]
746        let result = self.device.get(u8::from(DmxBrickletFunction::GetBootloaderMode), &payload).await?;
747        Ok(u8::from_le_byte_slice(result.body()))
748    }
749
750    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
751    /// to be increased by chunks of size 64. The data is written to flash
752    /// every 4 chunks (which equals to one page of size 256).
753    ///
754    /// This function is used by Brick Viewer during flashing. It should not be
755    /// necessary to call it in a normal user program.
756    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
757        let mut payload = [0; 4];
758        pointer.write_to_slice(&mut payload[0..4]);
759
760        #[allow(unused_variables)]
761        let result = self.device.set(u8::from(DmxBrickletFunction::SetWriteFirmwarePointer), &payload).await?;
762        Ok(())
763    }
764
765    /// Writes 64 Bytes of firmware at the position as written by
766    /// [`set_write_firmware_pointer`] before. The firmware is written
767    /// to flash every 4 chunks.
768    ///
769    /// You can only write firmware in bootloader mode.
770    ///
771    /// This function is used by Brick Viewer during flashing. It should not be
772    /// necessary to call it in a normal user program.
773    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
774        let mut payload = [0; 64];
775        data.write_to_slice(&mut payload[0..64]);
776
777        #[allow(unused_variables)]
778        let result = self.device.get(u8::from(DmxBrickletFunction::WriteFirmware), &payload).await?;
779        Ok(u8::from_le_byte_slice(result.body()))
780    }
781
782    /// Sets the status LED configuration. By default the LED shows
783    /// communication traffic between Brick and Bricklet, it flickers once
784    /// for every 10 received data packets.
785    ///
786    /// You can also turn the LED permanently on/off or show a heartbeat.
787    ///
788    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
789    ///
790    /// Associated constants:
791    /// * DMX_BRICKLET_STATUS_LED_CONFIG_OFF
792    ///	* DMX_BRICKLET_STATUS_LED_CONFIG_ON
793    ///	* DMX_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
794    ///	* DMX_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
795    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
796        let mut payload = [0; 1];
797        config.write_to_slice(&mut payload[0..1]);
798
799        #[allow(unused_variables)]
800        let result = self.device.set(u8::from(DmxBrickletFunction::SetStatusLedConfig), &payload).await?;
801        Ok(())
802    }
803
804    /// Returns the configuration as set by [`set_status_led_config`]
805    ///
806    /// Associated constants:
807    /// * DMX_BRICKLET_STATUS_LED_CONFIG_OFF
808    ///	* DMX_BRICKLET_STATUS_LED_CONFIG_ON
809    ///	* DMX_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
810    ///	* DMX_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
811    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
812        let payload = [0; 0];
813
814        #[allow(unused_variables)]
815        let result = self.device.get(u8::from(DmxBrickletFunction::GetStatusLedConfig), &payload).await?;
816        Ok(u8::from_le_byte_slice(result.body()))
817    }
818
819    /// Returns the temperature as measured inside the microcontroller. The
820    /// value returned is not the ambient temperature!
821    ///
822    /// The temperature is only proportional to the real temperature and it has bad
823    /// accuracy. Practically it is only useful as an indicator for
824    /// temperature changes.
825    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
826        let payload = [0; 0];
827
828        #[allow(unused_variables)]
829        let result = self.device.get(u8::from(DmxBrickletFunction::GetChipTemperature), &payload).await?;
830        Ok(i16::from_le_byte_slice(result.body()))
831    }
832
833    /// Calling this function will reset the Bricklet. All configurations
834    /// will be lost.
835    ///
836    /// After a reset you have to create new device objects,
837    /// calling functions on the existing ones will result in
838    /// undefined behavior!
839    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
840        let payload = [0; 0];
841
842        #[allow(unused_variables)]
843        let result = self.device.set(u8::from(DmxBrickletFunction::Reset), &payload).await?;
844        Ok(())
845    }
846
847    /// Writes a new UID into flash. If you want to set a new UID
848    /// you have to decode the Base58 encoded UID string into an
849    /// integer first.
850    ///
851    /// We recommend that you use Brick Viewer to change the UID.
852    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
853        let mut payload = [0; 4];
854        uid.write_to_slice(&mut payload[0..4]);
855
856        #[allow(unused_variables)]
857        let result = self.device.set(u8::from(DmxBrickletFunction::WriteUid), &payload).await?;
858        Ok(())
859    }
860
861    /// Returns the current UID as an integer. Encode as
862    /// Base58 to get the usual string version.
863    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
864        let payload = [0; 0];
865
866        #[allow(unused_variables)]
867        let result = self.device.get(u8::from(DmxBrickletFunction::ReadUid), &payload).await?;
868        Ok(u32::from_le_byte_slice(result.body()))
869    }
870
871    /// Returns the UID, the UID where the Bricklet is connected to,
872    /// the position, the hardware and firmware version as well as the
873    /// device identifier.
874    ///
875    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
876    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
877    /// position 'z'.
878    ///
879    /// The device identifier numbers can be found [here](device_identifier).
880    /// |device_identifier_constant|
881    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
882        let payload = [0; 0];
883
884        #[allow(unused_variables)]
885        let result = self.device.get(u8::from(DmxBrickletFunction::GetIdentity), &payload).await?;
886        Ok(Identity::from_le_byte_slice(result.body()))
887    }
888}