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}