tinkerforge_async/bindings/
can_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//! Communicates with CAN bus devices.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/CAN_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17    low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum CanBrickletFunction {
24    WriteFrame,
25    ReadFrame,
26    EnableFrameReadCallback,
27    DisableFrameReadCallback,
28    IsFrameReadCallbackEnabled,
29    SetConfiguration,
30    GetConfiguration,
31    SetReadFilter,
32    GetReadFilter,
33    GetErrorLog,
34    SetFrameReadableCallbackConfiguration,
35    GetFrameReadableCallbackConfiguration,
36    GetIdentity,
37    CallbackFrameRead,
38    CallbackFrameReadable,
39}
40impl From<CanBrickletFunction> for u8 {
41    fn from(fun: CanBrickletFunction) -> Self {
42        match fun {
43            CanBrickletFunction::WriteFrame => 1,
44            CanBrickletFunction::ReadFrame => 2,
45            CanBrickletFunction::EnableFrameReadCallback => 3,
46            CanBrickletFunction::DisableFrameReadCallback => 4,
47            CanBrickletFunction::IsFrameReadCallbackEnabled => 5,
48            CanBrickletFunction::SetConfiguration => 6,
49            CanBrickletFunction::GetConfiguration => 7,
50            CanBrickletFunction::SetReadFilter => 8,
51            CanBrickletFunction::GetReadFilter => 9,
52            CanBrickletFunction::GetErrorLog => 10,
53            CanBrickletFunction::SetFrameReadableCallbackConfiguration => 12,
54            CanBrickletFunction::GetFrameReadableCallbackConfiguration => 13,
55            CanBrickletFunction::GetIdentity => 255,
56            CanBrickletFunction::CallbackFrameRead => 11,
57            CanBrickletFunction::CallbackFrameReadable => 14,
58        }
59    }
60}
61pub const CAN_BRICKLET_FRAME_TYPE_STANDARD_DATA: u8 = 0;
62pub const CAN_BRICKLET_FRAME_TYPE_STANDARD_REMOTE: u8 = 1;
63pub const CAN_BRICKLET_FRAME_TYPE_EXTENDED_DATA: u8 = 2;
64pub const CAN_BRICKLET_FRAME_TYPE_EXTENDED_REMOTE: u8 = 3;
65pub const CAN_BRICKLET_BAUD_RATE_10KBPS: u8 = 0;
66pub const CAN_BRICKLET_BAUD_RATE_20KBPS: u8 = 1;
67pub const CAN_BRICKLET_BAUD_RATE_50KBPS: u8 = 2;
68pub const CAN_BRICKLET_BAUD_RATE_125KBPS: u8 = 3;
69pub const CAN_BRICKLET_BAUD_RATE_250KBPS: u8 = 4;
70pub const CAN_BRICKLET_BAUD_RATE_500KBPS: u8 = 5;
71pub const CAN_BRICKLET_BAUD_RATE_800KBPS: u8 = 6;
72pub const CAN_BRICKLET_BAUD_RATE_1000KBPS: u8 = 7;
73pub const CAN_BRICKLET_TRANSCEIVER_MODE_NORMAL: u8 = 0;
74pub const CAN_BRICKLET_TRANSCEIVER_MODE_LOOPBACK: u8 = 1;
75pub const CAN_BRICKLET_TRANSCEIVER_MODE_READ_ONLY: u8 = 2;
76pub const CAN_BRICKLET_FILTER_MODE_DISABLED: u8 = 0;
77pub const CAN_BRICKLET_FILTER_MODE_ACCEPT_ALL: u8 = 1;
78pub const CAN_BRICKLET_FILTER_MODE_MATCH_STANDARD: u8 = 2;
79pub const CAN_BRICKLET_FILTER_MODE_MATCH_STANDARD_AND_DATA: u8 = 3;
80pub const CAN_BRICKLET_FILTER_MODE_MATCH_EXTENDED: u8 = 4;
81
82#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
83pub struct ReadFrame {
84    pub success: bool,
85    pub frame_type: u8,
86    pub identifier: u32,
87    pub data: [u8; 8],
88    pub length: u8,
89}
90impl FromByteSlice for ReadFrame {
91    fn bytes_expected() -> usize {
92        15
93    }
94    fn from_le_byte_slice(bytes: &[u8]) -> ReadFrame {
95        ReadFrame {
96            success: <bool>::from_le_byte_slice(&bytes[0..1]),
97            frame_type: <u8>::from_le_byte_slice(&bytes[1..2]),
98            identifier: <u32>::from_le_byte_slice(&bytes[2..6]),
99            data: <[u8; 8]>::from_le_byte_slice(&bytes[6..14]),
100            length: <u8>::from_le_byte_slice(&bytes[14..15]),
101        }
102    }
103}
104
105#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
106pub struct Configuration {
107    pub baud_rate: u8,
108    pub transceiver_mode: u8,
109    pub write_timeout: i32,
110}
111impl FromByteSlice for Configuration {
112    fn bytes_expected() -> usize {
113        6
114    }
115    fn from_le_byte_slice(bytes: &[u8]) -> Configuration {
116        Configuration {
117            baud_rate: <u8>::from_le_byte_slice(&bytes[0..1]),
118            transceiver_mode: <u8>::from_le_byte_slice(&bytes[1..2]),
119            write_timeout: <i32>::from_le_byte_slice(&bytes[2..6]),
120        }
121    }
122}
123
124#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
125pub struct ReadFilter {
126    pub mode: u8,
127    pub mask: u32,
128    pub filter1: u32,
129    pub filter2: u32,
130}
131impl FromByteSlice for ReadFilter {
132    fn bytes_expected() -> usize {
133        13
134    }
135    fn from_le_byte_slice(bytes: &[u8]) -> ReadFilter {
136        ReadFilter {
137            mode: <u8>::from_le_byte_slice(&bytes[0..1]),
138            mask: <u32>::from_le_byte_slice(&bytes[1..5]),
139            filter1: <u32>::from_le_byte_slice(&bytes[5..9]),
140            filter2: <u32>::from_le_byte_slice(&bytes[9..13]),
141        }
142    }
143}
144
145#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
146pub struct ErrorLog {
147    pub write_error_level: u8,
148    pub read_error_level: u8,
149    pub transceiver_disabled: bool,
150    pub write_timeout_count: u32,
151    pub read_register_overflow_count: u32,
152    pub read_buffer_overflow_count: u32,
153}
154impl FromByteSlice for ErrorLog {
155    fn bytes_expected() -> usize {
156        15
157    }
158    fn from_le_byte_slice(bytes: &[u8]) -> ErrorLog {
159        ErrorLog {
160            write_error_level: <u8>::from_le_byte_slice(&bytes[0..1]),
161            read_error_level: <u8>::from_le_byte_slice(&bytes[1..2]),
162            transceiver_disabled: <bool>::from_le_byte_slice(&bytes[2..3]),
163            write_timeout_count: <u32>::from_le_byte_slice(&bytes[3..7]),
164            read_register_overflow_count: <u32>::from_le_byte_slice(&bytes[7..11]),
165            read_buffer_overflow_count: <u32>::from_le_byte_slice(&bytes[11..15]),
166        }
167    }
168}
169
170#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
171pub struct FrameReadEvent {
172    pub frame_type: u8,
173    pub identifier: u32,
174    pub data: [u8; 8],
175    pub length: u8,
176}
177impl FromByteSlice for FrameReadEvent {
178    fn bytes_expected() -> usize {
179        14
180    }
181    fn from_le_byte_slice(bytes: &[u8]) -> FrameReadEvent {
182        FrameReadEvent {
183            frame_type: <u8>::from_le_byte_slice(&bytes[0..1]),
184            identifier: <u32>::from_le_byte_slice(&bytes[1..5]),
185            data: <[u8; 8]>::from_le_byte_slice(&bytes[5..13]),
186            length: <u8>::from_le_byte_slice(&bytes[13..14]),
187        }
188    }
189}
190
191#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
192pub struct Identity {
193    pub uid: String,
194    pub connected_uid: String,
195    pub position: char,
196    pub hardware_version: [u8; 3],
197    pub firmware_version: [u8; 3],
198    pub device_identifier: u16,
199}
200impl FromByteSlice for Identity {
201    fn bytes_expected() -> usize {
202        25
203    }
204    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
205        Identity {
206            uid: <String>::from_le_byte_slice(&bytes[0..8]),
207            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
208            position: <char>::from_le_byte_slice(&bytes[16..17]),
209            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
210            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
211            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
212        }
213    }
214}
215
216/// Communicates with CAN bus devices
217#[derive(Clone)]
218pub struct CanBricklet {
219    device: Device,
220}
221impl CanBricklet {
222    pub const DEVICE_IDENTIFIER: u16 = 270;
223    pub const DEVICE_DISPLAY_NAME: &'static str = "CAN Bricklet";
224    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
225    pub fn new(uid: Uid, connection: AsyncIpConnection) -> CanBricklet {
226        let mut result = CanBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
227        result.device.response_expected[u8::from(CanBrickletFunction::WriteFrame) as usize] = ResponseExpectedFlag::AlwaysTrue;
228        result.device.response_expected[u8::from(CanBrickletFunction::ReadFrame) as usize] = ResponseExpectedFlag::AlwaysTrue;
229        result.device.response_expected[u8::from(CanBrickletFunction::EnableFrameReadCallback) as usize] = ResponseExpectedFlag::True;
230        result.device.response_expected[u8::from(CanBrickletFunction::DisableFrameReadCallback) as usize] = ResponseExpectedFlag::True;
231        result.device.response_expected[u8::from(CanBrickletFunction::IsFrameReadCallbackEnabled) as usize] =
232            ResponseExpectedFlag::AlwaysTrue;
233        result.device.response_expected[u8::from(CanBrickletFunction::SetConfiguration) as usize] = ResponseExpectedFlag::False;
234        result.device.response_expected[u8::from(CanBrickletFunction::GetConfiguration) as usize] = ResponseExpectedFlag::AlwaysTrue;
235        result.device.response_expected[u8::from(CanBrickletFunction::SetReadFilter) as usize] = ResponseExpectedFlag::False;
236        result.device.response_expected[u8::from(CanBrickletFunction::GetReadFilter) as usize] = ResponseExpectedFlag::AlwaysTrue;
237        result.device.response_expected[u8::from(CanBrickletFunction::GetErrorLog) as usize] = ResponseExpectedFlag::AlwaysTrue;
238        result.device.response_expected[u8::from(CanBrickletFunction::SetFrameReadableCallbackConfiguration) as usize] =
239            ResponseExpectedFlag::True;
240        result.device.response_expected[u8::from(CanBrickletFunction::GetFrameReadableCallbackConfiguration) as usize] =
241            ResponseExpectedFlag::AlwaysTrue;
242        result.device.response_expected[u8::from(CanBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
243        result
244    }
245
246    /// Returns the response expected flag for the function specified by the function ID parameter.
247    /// It is true if the function is expected to send a response, false otherwise.
248    ///
249    /// For getter functions this is enabled by default and cannot be disabled, because those
250    /// functions will always send a response. For callback configuration functions it is enabled
251    /// by default too, but can be disabled by [`set_response_expected`](crate::can_bricklet::CanBricklet::set_response_expected).
252    /// For setter functions it is disabled by default and can be enabled.
253    ///
254    /// Enabling the response expected flag for a setter function allows to detect timeouts
255    /// and other error conditions calls of this setter as well. The device will then send a response
256    /// for this purpose. If this flag is disabled for a setter function then no response is sent
257    /// and errors are silently ignored, because they cannot be detected.
258    ///
259    /// See [`set_response_expected`](crate::can_bricklet::CanBricklet::set_response_expected) for the list of function ID constants available for this function.
260    pub fn get_response_expected(&mut self, fun: CanBrickletFunction) -> Result<bool, GetResponseExpectedError> {
261        self.device.get_response_expected(u8::from(fun))
262    }
263
264    /// Changes the response expected flag of the function specified by the function ID parameter.
265    /// This flag can only be changed for setter (default value: false) and callback configuration
266    /// functions (default value: true). For getter functions it is always enabled.
267    ///
268    /// Enabling the response expected flag for a setter function allows to detect timeouts and
269    /// other error conditions calls of this setter as well. The device will then send a response
270    /// for this purpose. If this flag is disabled for a setter function then no response is sent
271    /// and errors are silently ignored, because they cannot be detected.
272    pub fn set_response_expected(&mut self, fun: CanBrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
273        self.device.set_response_expected(u8::from(fun), response_expected)
274    }
275
276    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
277    pub fn set_response_expected_all(&mut self, response_expected: bool) {
278        self.device.set_response_expected_all(response_expected)
279    }
280
281    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
282    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
283    pub fn get_api_version(&self) -> [u8; 3] {
284        self.device.api_version
285    }
286
287    /// This receiver is triggered if a data or remote frame was received by the CAN
288    /// transceiver.
289    ///
290    /// The ``identifier`` return value follows the identifier format described for
291    /// [`write_frame`].
292    ///
293    /// For remote frames the ``data`` return value always contains invalid values.
294    ///
295    /// A configurable read filter can be used to define which frames should be
296    /// received by the CAN transceiver at all (see [`set_read_filter`]).
297    ///
298    /// To enable this receiver, use [`enable_frame_read_callback`].
299    ///
300    /// [`write_frame`]: #method.write_frame
301    /// [`enable_frame_read_callback`]: #method.enable_frame_read_callback
302    /// [`set_read_filter`]: #method.set_read_filter
303    pub async fn get_frame_read_callback_receiver(&mut self) -> impl Stream<Item = FrameReadEvent> {
304        self.device
305            .get_callback_receiver(u8::from(CanBrickletFunction::CallbackFrameRead))
306            .await
307            .map(|p| FrameReadEvent::from_le_byte_slice(p.body()))
308    }
309
310    /// This receiver is triggered if a data or remote frame was received by the CAN
311    /// transceiver. The received frame can be read with [`read_frame`].
312    /// If additional frames are received, but [`read_frame`] was not called yet, the receiver
313    /// will not trigger again.
314    ///
315    /// A configurable read filter can be used to define which frames should be
316    /// received by the CAN transceiver and put into the read queue (see
317    /// [`set_read_filter`]).
318    ///
319    /// To enable this receiver, use [`set_frame_readable_callback_configuration`].
320    ///
321    ///
322    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
323    pub async fn get_frame_readable_callback_receiver(&mut self) -> impl Stream<Item = ()> {
324        self.device.get_callback_receiver(u8::from(CanBrickletFunction::CallbackFrameReadable)).await.map(|_p| ())
325    }
326
327    /// Writes a data or remote frame to the write buffer to be transmitted over the
328    /// CAN transceiver.
329    ///
330    /// The Bricklet supports the standard 11-bit (CAN 2.0A) and the additional extended
331    /// 18-bit (CAN 2.0B) identifiers. For standard frames the Bricklet uses bit 0 to 10
332    /// from the ``identifier`` parameter as standard 11-bit identifier. For extended
333    /// frames the Bricklet additionally uses bit 11 to 28 from the ``identifier``
334    /// parameter as extended 18-bit identifier.
335    ///
336    /// For remote frames the ``data`` parameter is ignored.
337    ///
338    /// Returns *true* if the frame was successfully added to the write buffer. Returns
339    /// *false* if the frame could not be added because write buffer is already full.
340    ///
341    /// The write buffer can overflow if frames are written to it at a higher rate
342    /// than the Bricklet can transmitted them over the CAN transceiver. This may
343    /// happen if the CAN transceiver is configured as read-only or is using a low baud
344    /// rate (see [`set_configuration`]). It can also happen if the CAN bus is
345    /// congested and the frame cannot be transmitted because it constantly loses
346    /// arbitration or because the CAN transceiver is currently disabled due to a high
347    /// write error level (see [`get_error_log`]).
348    ///
349    /// Associated constants:
350    /// * CAN_BRICKLET_FRAME_TYPE_STANDARD_DATA
351    ///	* CAN_BRICKLET_FRAME_TYPE_STANDARD_REMOTE
352    ///	* CAN_BRICKLET_FRAME_TYPE_EXTENDED_DATA
353    ///	* CAN_BRICKLET_FRAME_TYPE_EXTENDED_REMOTE
354    pub async fn write_frame(&mut self, frame_type: u8, identifier: u32, data: &[u8; 8], length: u8) -> Result<bool, TinkerforgeError> {
355        let mut payload = [0; 14];
356        frame_type.write_to_slice(&mut payload[0..1]);
357        identifier.write_to_slice(&mut payload[1..5]);
358        data.write_to_slice(&mut payload[5..13]);
359        length.write_to_slice(&mut payload[13..14]);
360
361        #[allow(unused_variables)]
362        let result = self.device.get(u8::from(CanBrickletFunction::WriteFrame), &payload).await?;
363        Ok(bool::from_le_byte_slice(result.body()))
364    }
365
366    /// Tries to read the next data or remote frame from the read buffer and return it.
367    /// If a frame was successfully read, then the ``success`` return value is set to
368    /// *true* and the other return values contain the frame. If the read buffer is
369    /// empty and no frame could be read, then the ``success`` return value is set to
370    /// *false* and the other return values contain invalid data.
371    ///
372    /// The ``identifier`` return value follows the identifier format described for
373    /// [`write_frame`].
374    ///
375    /// For remote frames the ``data`` return value always contains invalid data.
376    ///
377    /// A configurable read filter can be used to define which frames should be
378    /// received by the CAN transceiver and put into the read buffer (see
379    /// [`set_read_filter`]).
380    ///
381    /// Instead of polling with this function, you can also use receivers. See the
382    /// [`enable_frame_read_callback`] function and the [`get_frame_read_callback_receiver`] receiver.
383    ///
384    /// Associated constants:
385    /// * CAN_BRICKLET_FRAME_TYPE_STANDARD_DATA
386    ///	* CAN_BRICKLET_FRAME_TYPE_STANDARD_REMOTE
387    ///	* CAN_BRICKLET_FRAME_TYPE_EXTENDED_DATA
388    ///	* CAN_BRICKLET_FRAME_TYPE_EXTENDED_REMOTE
389    pub async fn read_frame(&mut self) -> Result<ReadFrame, TinkerforgeError> {
390        let payload = [0; 0];
391
392        #[allow(unused_variables)]
393        let result = self.device.get(u8::from(CanBrickletFunction::ReadFrame), &payload).await?;
394        Ok(ReadFrame::from_le_byte_slice(result.body()))
395    }
396
397    /// Enables the [`get_frame_read_callback_receiver`] receiver.
398    ///
399    /// By default the receiver is disabled. Enabling this receiver will disable the [`get_frame_readable_callback_receiver`] receiver.
400    pub async fn enable_frame_read_callback(&mut self) -> Result<(), TinkerforgeError> {
401        let payload = [0; 0];
402
403        #[allow(unused_variables)]
404        let result = self.device.set(u8::from(CanBrickletFunction::EnableFrameReadCallback), &payload).await?;
405        Ok(())
406    }
407
408    /// Disables the [`get_frame_read_callback_receiver`] receiver.
409    ///
410    /// By default the receiver is disabled.
411    pub async fn disable_frame_read_callback(&mut self) -> Result<(), TinkerforgeError> {
412        let payload = [0; 0];
413
414        #[allow(unused_variables)]
415        let result = self.device.set(u8::from(CanBrickletFunction::DisableFrameReadCallback), &payload).await?;
416        Ok(())
417    }
418
419    /// Returns *true* if the [`get_frame_read_callback_receiver`] receiver is enabled, *false* otherwise.
420    pub async fn is_frame_read_callback_enabled(&mut self) -> Result<bool, TinkerforgeError> {
421        let payload = [0; 0];
422
423        #[allow(unused_variables)]
424        let result = self.device.get(u8::from(CanBrickletFunction::IsFrameReadCallbackEnabled), &payload).await?;
425        Ok(bool::from_le_byte_slice(result.body()))
426    }
427
428    /// Sets the configuration for the CAN bus communication.
429    ///
430    /// The baud rate can be configured in steps between 10 and 1000 kbit/s.
431    ///
432    /// The CAN transceiver has three different modes:
433    ///
434    /// * Normal: Reads from and writes to the CAN bus and performs active bus
435    ///   error detection and acknowledgement.
436    /// * Loopback: All reads and writes are performed internally. The transceiver
437    ///   is disconnected from the actual CAN bus.
438    /// * Read-Only: Only reads from the CAN bus, but does neither active bus error
439    ///   detection nor acknowledgement. Only the receiving part of the transceiver
440    ///   is connected to the CAN bus.
441    ///
442    /// The write timeout has three different modes that define how a failed frame
443    /// transmission should be handled:
444    ///
445    /// * One-Shot (= -1): Only one transmission attempt will be made. If the
446    ///   transmission fails then the frame is discarded.
447    /// * Infinite (= 0): Infinite transmission attempts will be made. The frame will
448    ///   never be discarded.
449    /// * Milliseconds (> 0): A limited number of transmission attempts will be made.
450    ///   If the frame could not be transmitted successfully after the configured
451    ///   number of milliseconds then the frame is discarded.
452    ///
453    /// Associated constants:
454    /// * CAN_BRICKLET_BAUD_RATE_10KBPS
455    ///	* CAN_BRICKLET_BAUD_RATE_20KBPS
456    ///	* CAN_BRICKLET_BAUD_RATE_50KBPS
457    ///	* CAN_BRICKLET_BAUD_RATE_125KBPS
458    ///	* CAN_BRICKLET_BAUD_RATE_250KBPS
459    ///	* CAN_BRICKLET_BAUD_RATE_500KBPS
460    ///	* CAN_BRICKLET_BAUD_RATE_800KBPS
461    ///	* CAN_BRICKLET_BAUD_RATE_1000KBPS
462    ///	* CAN_BRICKLET_TRANSCEIVER_MODE_NORMAL
463    ///	* CAN_BRICKLET_TRANSCEIVER_MODE_LOOPBACK
464    ///	* CAN_BRICKLET_TRANSCEIVER_MODE_READ_ONLY
465    pub async fn set_configuration(&mut self, baud_rate: u8, transceiver_mode: u8, write_timeout: i32) -> Result<(), TinkerforgeError> {
466        let mut payload = [0; 6];
467        baud_rate.write_to_slice(&mut payload[0..1]);
468        transceiver_mode.write_to_slice(&mut payload[1..2]);
469        write_timeout.write_to_slice(&mut payload[2..6]);
470
471        #[allow(unused_variables)]
472        let result = self.device.set(u8::from(CanBrickletFunction::SetConfiguration), &payload).await?;
473        Ok(())
474    }
475
476    /// Returns the configuration as set by [`set_configuration`].
477    ///
478    /// Associated constants:
479    /// * CAN_BRICKLET_BAUD_RATE_10KBPS
480    ///	* CAN_BRICKLET_BAUD_RATE_20KBPS
481    ///	* CAN_BRICKLET_BAUD_RATE_50KBPS
482    ///	* CAN_BRICKLET_BAUD_RATE_125KBPS
483    ///	* CAN_BRICKLET_BAUD_RATE_250KBPS
484    ///	* CAN_BRICKLET_BAUD_RATE_500KBPS
485    ///	* CAN_BRICKLET_BAUD_RATE_800KBPS
486    ///	* CAN_BRICKLET_BAUD_RATE_1000KBPS
487    ///	* CAN_BRICKLET_TRANSCEIVER_MODE_NORMAL
488    ///	* CAN_BRICKLET_TRANSCEIVER_MODE_LOOPBACK
489    ///	* CAN_BRICKLET_TRANSCEIVER_MODE_READ_ONLY
490    pub async fn get_configuration(&mut self) -> Result<Configuration, TinkerforgeError> {
491        let payload = [0; 0];
492
493        #[allow(unused_variables)]
494        let result = self.device.get(u8::from(CanBrickletFunction::GetConfiguration), &payload).await?;
495        Ok(Configuration::from_le_byte_slice(result.body()))
496    }
497
498    /// Set the read filter configuration. This can be used to define which frames
499    /// should be received by the CAN transceiver and put into the read buffer.
500    ///
501    /// The read filter has five different modes that define if and how the mask and
502    /// the two filters are applied:
503    ///
504    /// * Disabled: No filtering is applied at all. All frames are received even
505    ///   incomplete and defective frames. This mode should be used for debugging only.
506    /// * Accept-All: All complete and error-free frames are received.
507    /// * Match-Standard: Only standard frames with a matching identifier are received.
508    /// * Match-Standard-and-Data: Only standard frames with matching identifier and
509    ///   data bytes are received.
510    /// * Match-Extended: Only extended frames with a matching identifier are received.
511    ///
512    /// The mask and filters are used as bit masks. Their usage depends on the mode:
513    ///
514    /// * Disabled: Mask and filters are ignored.
515    /// * Accept-All: Mask and filters are ignored.
516    /// * Match-Standard: Bit 0 to 10 (11 bits) of mask and filters are used to match
517    ///   the 11-bit identifier of standard frames.
518    /// * Match-Standard-and-Data: Bit 0 to 10 (11 bits) of mask and filters are used
519    ///   to match the 11-bit identifier of standard frames. Bit 11 to 18 (8 bits) and
520    ///   bit 19 to 26 (8 bits) of mask and filters are used to match the first and
521    ///   second data byte (if present) of standard frames.
522    /// * Match-Extended: Bit 0 to 10 (11 bits) of mask and filters are used
523    ///   to match the standard 11-bit identifier part of extended frames. Bit 11 to 28
524    ///   (18 bits) of mask and filters are used to match the extended 18-bit identifier
525    ///   part of extended frames.
526    ///
527    /// The mask and filters are applied in this way: The mask is used to select the
528    /// identifier and data bits that should be compared to the corresponding filter
529    /// bits. All unselected bits are automatically accepted. All selected bits have
530    /// to match one of the filters to be accepted. If all bits for the selected mode
531    /// are accepted then the frame is accepted and is added to the read buffer.
532    ///
533    ///  Mask Bit| Filter Bit| Identifier/Data Bit| Result
534    ///  --- | --- | --- | ---
535    ///  0| X| X| Accept
536    ///  1| 0| 0| Accept
537    ///  1| 0| 1| Reject
538    ///  1| 1| 0| Reject
539    ///  1| 1| 1| Accept
540    ///
541    /// For example, to receive standard frames with identifier 0x123 only the mode can
542    /// be set to Match-Standard with 0x7FF as mask and 0x123 as filter 1 and filter 2.
543    /// The mask of 0x7FF selects all 11 identifier bits for matching so that the
544    /// identifier has to be exactly 0x123 to be accepted.
545    ///
546    /// To accept identifier 0x123 and identifier 0x456 at the same time, just set
547    /// filter 2 to 0x456 and keep mask and filter 1 unchanged.
548    ///
549    /// Associated constants:
550    /// * CAN_BRICKLET_FILTER_MODE_DISABLED
551    ///	* CAN_BRICKLET_FILTER_MODE_ACCEPT_ALL
552    ///	* CAN_BRICKLET_FILTER_MODE_MATCH_STANDARD
553    ///	* CAN_BRICKLET_FILTER_MODE_MATCH_STANDARD_AND_DATA
554    ///	* CAN_BRICKLET_FILTER_MODE_MATCH_EXTENDED
555    pub async fn set_read_filter(&mut self, mode: u8, mask: u32, filter1: u32, filter2: u32) -> Result<(), TinkerforgeError> {
556        let mut payload = [0; 13];
557        mode.write_to_slice(&mut payload[0..1]);
558        mask.write_to_slice(&mut payload[1..5]);
559        filter1.write_to_slice(&mut payload[5..9]);
560        filter2.write_to_slice(&mut payload[9..13]);
561
562        #[allow(unused_variables)]
563        let result = self.device.set(u8::from(CanBrickletFunction::SetReadFilter), &payload).await?;
564        Ok(())
565    }
566
567    /// Returns the read filter as set by [`set_read_filter`].
568    ///
569    /// Associated constants:
570    /// * CAN_BRICKLET_FILTER_MODE_DISABLED
571    ///	* CAN_BRICKLET_FILTER_MODE_ACCEPT_ALL
572    ///	* CAN_BRICKLET_FILTER_MODE_MATCH_STANDARD
573    ///	* CAN_BRICKLET_FILTER_MODE_MATCH_STANDARD_AND_DATA
574    ///	* CAN_BRICKLET_FILTER_MODE_MATCH_EXTENDED
575    pub async fn get_read_filter(&mut self) -> Result<ReadFilter, TinkerforgeError> {
576        let payload = [0; 0];
577
578        #[allow(unused_variables)]
579        let result = self.device.get(u8::from(CanBrickletFunction::GetReadFilter), &payload).await?;
580        Ok(ReadFilter::from_le_byte_slice(result.body()))
581    }
582
583    /// Returns information about different kinds of errors.
584    ///
585    /// The write and read error levels indicate the current level of checksum,
586    /// acknowledgement, form, bit and stuffing errors during CAN bus write and read
587    /// operations.
588    ///
589    /// When the write error level exceeds 255 then the CAN transceiver gets disabled
590    /// and no frames can be transmitted or received anymore. The CAN transceiver will
591    /// automatically be activated again after the CAN bus is idle for a while.
592    ///
593    /// The write and read error levels are not available in read-only transceiver mode
594    /// (see [`set_configuration`]) and are reset to 0 as a side effect of changing
595    /// the configuration or the read filter.
596    ///
597    /// The write timeout, read register and buffer overflow counts represents the
598    /// number of these errors:
599    ///
600    /// * A write timeout occurs if a frame could not be transmitted before the
601    ///   configured write timeout expired (see [`set_configuration`]).
602    /// * A read register overflow occurs if the read register of the CAN transceiver
603    ///   still contains the last received frame when the next frame arrives. In this
604    ///   case the newly arrived frame is lost. This happens if the CAN transceiver
605    ///   receives more frames than the Bricklet can handle. Using the read filter
606    ///   (see [`set_read_filter`]) can help to reduce the amount of received frames.
607    ///   This count is not exact, but a lower bound, because the Bricklet might not
608    ///   able detect all overflows if they occur in rapid succession.
609    /// * A read buffer overflow occurs if the read buffer of the Bricklet is already
610    ///   full when the next frame should be read from the read register of the CAN
611    ///   transceiver. In this case the frame in the read register is lost. This
612    ///   happens if the CAN transceiver receives more frames to be added to the read
613    ///   buffer than are removed from the read buffer using the [`read_frame`]
614    ///   function. Using the [`get_frame_read_callback_receiver`] receiver ensures that the read buffer
615    ///   can not overflow.
616    pub async fn get_error_log(&mut self) -> Result<ErrorLog, TinkerforgeError> {
617        let payload = [0; 0];
618
619        #[allow(unused_variables)]
620        let result = self.device.get(u8::from(CanBrickletFunction::GetErrorLog), &payload).await?;
621        Ok(ErrorLog::from_le_byte_slice(result.body()))
622    }
623
624    /// Enables/disables the [`get_frame_readable_callback_receiver`] receiver.
625    ///
626    /// By default the receiver is disabled. Enabling this receiver will disable the [`get_frame_read_callback_receiver`] receiver.
627    ///
628    ///
629    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
630    pub async fn set_frame_readable_callback_configuration(&mut self, enabled: bool) -> Result<(), TinkerforgeError> {
631        let mut payload = [0; 1];
632        enabled.write_to_slice(&mut payload[0..1]);
633
634        #[allow(unused_variables)]
635        let result = self.device.set(u8::from(CanBrickletFunction::SetFrameReadableCallbackConfiguration), &payload).await?;
636        Ok(())
637    }
638
639    /// Returns *true* if the [`get_frame_readable_callback_receiver`] receiver is enabled, *false* otherwise.
640    ///
641    ///
642    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
643    pub async fn get_frame_readable_callback_configuration(&mut self) -> Result<bool, TinkerforgeError> {
644        let payload = [0; 0];
645
646        #[allow(unused_variables)]
647        let result = self.device.get(u8::from(CanBrickletFunction::GetFrameReadableCallbackConfiguration), &payload).await?;
648        Ok(bool::from_le_byte_slice(result.body()))
649    }
650
651    /// Returns the UID, the UID where the Bricklet is connected to,
652    /// the position, the hardware and firmware version as well as the
653    /// device identifier.
654    ///
655    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
656    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
657    /// position 'z'.
658    ///
659    /// The device identifier numbers can be found [here](device_identifier).
660    /// |device_identifier_constant|
661    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
662        let payload = [0; 0];
663
664        #[allow(unused_variables)]
665        let result = self.device.get(u8::from(CanBrickletFunction::GetIdentity), &payload).await?;
666        Ok(Identity::from_le_byte_slice(result.body()))
667    }
668}