tinkerforge/bindings/
dmx_bricklet.rs

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