tinkerforge/bindings/
can_v2_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//! Communicates with CAN bus devices.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/CANV2_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 CanV2BrickletFunction {
24    WriteFrameLowLevel,
25    ReadFrameLowLevel,
26    SetFrameReadCallbackConfiguration,
27    GetFrameReadCallbackConfiguration,
28    SetTransceiverConfiguration,
29    GetTransceiverConfiguration,
30    SetQueueConfigurationLowLevel,
31    GetQueueConfigurationLowLevel,
32    SetReadFilterConfiguration,
33    GetReadFilterConfiguration,
34    GetErrorLogLowLevel,
35    SetCommunicationLedConfig,
36    GetCommunicationLedConfig,
37    SetErrorLedConfig,
38    GetErrorLedConfig,
39    SetFrameReadableCallbackConfiguration,
40    GetFrameReadableCallbackConfiguration,
41    SetErrorOccurredCallbackConfiguration,
42    GetErrorOccurredCallbackConfiguration,
43    GetSpitfpErrorCount,
44    SetBootloaderMode,
45    GetBootloaderMode,
46    SetWriteFirmwarePointer,
47    WriteFirmware,
48    SetStatusLedConfig,
49    GetStatusLedConfig,
50    GetChipTemperature,
51    Reset,
52    WriteUid,
53    ReadUid,
54    GetIdentity,
55    CallbackFrameReadLowLevel,
56    CallbackFrameReadable,
57    CallbackErrorOccurred,
58}
59impl From<CanV2BrickletFunction> for u8 {
60    fn from(fun: CanV2BrickletFunction) -> Self {
61        match fun {
62            CanV2BrickletFunction::WriteFrameLowLevel => 1,
63            CanV2BrickletFunction::ReadFrameLowLevel => 2,
64            CanV2BrickletFunction::SetFrameReadCallbackConfiguration => 3,
65            CanV2BrickletFunction::GetFrameReadCallbackConfiguration => 4,
66            CanV2BrickletFunction::SetTransceiverConfiguration => 5,
67            CanV2BrickletFunction::GetTransceiverConfiguration => 6,
68            CanV2BrickletFunction::SetQueueConfigurationLowLevel => 7,
69            CanV2BrickletFunction::GetQueueConfigurationLowLevel => 8,
70            CanV2BrickletFunction::SetReadFilterConfiguration => 9,
71            CanV2BrickletFunction::GetReadFilterConfiguration => 10,
72            CanV2BrickletFunction::GetErrorLogLowLevel => 11,
73            CanV2BrickletFunction::SetCommunicationLedConfig => 12,
74            CanV2BrickletFunction::GetCommunicationLedConfig => 13,
75            CanV2BrickletFunction::SetErrorLedConfig => 14,
76            CanV2BrickletFunction::GetErrorLedConfig => 15,
77            CanV2BrickletFunction::SetFrameReadableCallbackConfiguration => 17,
78            CanV2BrickletFunction::GetFrameReadableCallbackConfiguration => 18,
79            CanV2BrickletFunction::SetErrorOccurredCallbackConfiguration => 20,
80            CanV2BrickletFunction::GetErrorOccurredCallbackConfiguration => 21,
81            CanV2BrickletFunction::GetSpitfpErrorCount => 234,
82            CanV2BrickletFunction::SetBootloaderMode => 235,
83            CanV2BrickletFunction::GetBootloaderMode => 236,
84            CanV2BrickletFunction::SetWriteFirmwarePointer => 237,
85            CanV2BrickletFunction::WriteFirmware => 238,
86            CanV2BrickletFunction::SetStatusLedConfig => 239,
87            CanV2BrickletFunction::GetStatusLedConfig => 240,
88            CanV2BrickletFunction::GetChipTemperature => 242,
89            CanV2BrickletFunction::Reset => 243,
90            CanV2BrickletFunction::WriteUid => 248,
91            CanV2BrickletFunction::ReadUid => 249,
92            CanV2BrickletFunction::GetIdentity => 255,
93            CanV2BrickletFunction::CallbackFrameReadLowLevel => 16,
94            CanV2BrickletFunction::CallbackFrameReadable => 19,
95            CanV2BrickletFunction::CallbackErrorOccurred => 22,
96        }
97    }
98}
99pub const CAN_V2_BRICKLET_FRAME_TYPE_STANDARD_DATA: u8 = 0;
100pub const CAN_V2_BRICKLET_FRAME_TYPE_STANDARD_REMOTE: u8 = 1;
101pub const CAN_V2_BRICKLET_FRAME_TYPE_EXTENDED_DATA: u8 = 2;
102pub const CAN_V2_BRICKLET_FRAME_TYPE_EXTENDED_REMOTE: u8 = 3;
103pub const CAN_V2_BRICKLET_TRANSCEIVER_MODE_NORMAL: u8 = 0;
104pub const CAN_V2_BRICKLET_TRANSCEIVER_MODE_LOOPBACK: u8 = 1;
105pub const CAN_V2_BRICKLET_TRANSCEIVER_MODE_READ_ONLY: u8 = 2;
106pub const CAN_V2_BRICKLET_FILTER_MODE_ACCEPT_ALL: u8 = 0;
107pub const CAN_V2_BRICKLET_FILTER_MODE_MATCH_STANDARD_ONLY: u8 = 1;
108pub const CAN_V2_BRICKLET_FILTER_MODE_MATCH_EXTENDED_ONLY: u8 = 2;
109pub const CAN_V2_BRICKLET_FILTER_MODE_MATCH_STANDARD_AND_EXTENDED: u8 = 3;
110pub const CAN_V2_BRICKLET_TRANSCEIVER_STATE_ACTIVE: u8 = 0;
111pub const CAN_V2_BRICKLET_TRANSCEIVER_STATE_PASSIVE: u8 = 1;
112pub const CAN_V2_BRICKLET_TRANSCEIVER_STATE_DISABLED: u8 = 2;
113pub const CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_OFF: u8 = 0;
114pub const CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_ON: u8 = 1;
115pub const CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
116pub const CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION: u8 = 3;
117pub const CAN_V2_BRICKLET_ERROR_LED_CONFIG_OFF: u8 = 0;
118pub const CAN_V2_BRICKLET_ERROR_LED_CONFIG_ON: u8 = 1;
119pub const CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
120pub const CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_TRANSCEIVER_STATE: u8 = 3;
121pub const CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR: u8 = 4;
122pub const CAN_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
123pub const CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
124pub const CAN_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
125pub const CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
126pub const CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
127pub const CAN_V2_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
128pub const CAN_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
129pub const CAN_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
130pub const CAN_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
131pub const CAN_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
132pub const CAN_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
133pub const CAN_V2_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
134pub const CAN_V2_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
135pub const CAN_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
136pub const CAN_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
137
138#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
139pub struct WriteFrameLowLevel {
140    pub success: bool,
141}
142impl FromByteSlice for WriteFrameLowLevel {
143    fn bytes_expected() -> usize { 1 }
144    fn from_le_byte_slice(bytes: &[u8]) -> WriteFrameLowLevel { WriteFrameLowLevel { success: <bool>::from_le_byte_slice(&bytes[0..1]) } }
145}
146impl LowLevelWrite<WriteFrameResult> for WriteFrameLowLevel {
147    fn ll_message_written(&self) -> usize { 15 }
148
149    fn get_result(&self) -> WriteFrameResult { WriteFrameResult { success: self.success } }
150}
151
152#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
153pub struct ReadFrameLowLevel {
154    pub success: bool,
155    pub frame_type: u8,
156    pub identifier: u32,
157    pub data_length: u8,
158    pub data_data: [u8; 15],
159}
160impl FromByteSlice for ReadFrameLowLevel {
161    fn bytes_expected() -> usize { 22 }
162    fn from_le_byte_slice(bytes: &[u8]) -> ReadFrameLowLevel {
163        ReadFrameLowLevel {
164            success: <bool>::from_le_byte_slice(&bytes[0..1]),
165            frame_type: <u8>::from_le_byte_slice(&bytes[1..2]),
166            identifier: <u32>::from_le_byte_slice(&bytes[2..6]),
167            data_length: <u8>::from_le_byte_slice(&bytes[6..7]),
168            data_data: <[u8; 15]>::from_le_byte_slice(&bytes[7..22]),
169        }
170    }
171}
172impl LowLevelRead<u8, ReadFrameResult> for ReadFrameLowLevel {
173    fn ll_message_length(&self) -> usize { self.data_length as usize }
174
175    fn ll_message_chunk_offset(&self) -> usize { 0 }
176
177    fn ll_message_chunk_data(&self) -> &[u8] { &self.data_data }
178
179    fn get_result(&self) -> ReadFrameResult {
180        ReadFrameResult { success: self.success, frame_type: self.frame_type, identifier: self.identifier }
181    }
182}
183
184#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
185pub struct TransceiverConfiguration {
186    pub baud_rate: u32,
187    pub sample_point: u16,
188    pub transceiver_mode: u8,
189}
190impl FromByteSlice for TransceiverConfiguration {
191    fn bytes_expected() -> usize { 7 }
192    fn from_le_byte_slice(bytes: &[u8]) -> TransceiverConfiguration {
193        TransceiverConfiguration {
194            baud_rate: <u32>::from_le_byte_slice(&bytes[0..4]),
195            sample_point: <u16>::from_le_byte_slice(&bytes[4..6]),
196            transceiver_mode: <u8>::from_le_byte_slice(&bytes[6..7]),
197        }
198    }
199}
200
201#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
202pub struct SetQueueConfigurationLowLevel {}
203impl FromByteSlice for SetQueueConfigurationLowLevel {
204    fn bytes_expected() -> usize { 0 }
205    fn from_le_byte_slice(_bytes: &[u8]) -> SetQueueConfigurationLowLevel { SetQueueConfigurationLowLevel {} }
206}
207impl LowLevelWrite<SetQueueConfigurationResult> for SetQueueConfigurationLowLevel {
208    fn ll_message_written(&self) -> usize { 32 }
209
210    fn get_result(&self) -> SetQueueConfigurationResult { SetQueueConfigurationResult {} }
211}
212
213#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
214pub struct QueueConfigurationLowLevel {
215    pub write_buffer_size: u8,
216    pub write_buffer_timeout: i32,
217    pub write_backlog_size: u16,
218    pub read_buffer_sizes_length: u8,
219    pub read_buffer_sizes_data: [i8; 32],
220    pub read_backlog_size: u16,
221}
222impl FromByteSlice for QueueConfigurationLowLevel {
223    fn bytes_expected() -> usize { 42 }
224    fn from_le_byte_slice(bytes: &[u8]) -> QueueConfigurationLowLevel {
225        QueueConfigurationLowLevel {
226            write_buffer_size: <u8>::from_le_byte_slice(&bytes[0..1]),
227            write_buffer_timeout: <i32>::from_le_byte_slice(&bytes[1..5]),
228            write_backlog_size: <u16>::from_le_byte_slice(&bytes[5..7]),
229            read_buffer_sizes_length: <u8>::from_le_byte_slice(&bytes[7..8]),
230            read_buffer_sizes_data: <[i8; 32]>::from_le_byte_slice(&bytes[8..40]),
231            read_backlog_size: <u16>::from_le_byte_slice(&bytes[40..42]),
232        }
233    }
234}
235impl LowLevelRead<i8, QueueConfigurationResult> for QueueConfigurationLowLevel {
236    fn ll_message_length(&self) -> usize { self.read_buffer_sizes_length as usize }
237
238    fn ll_message_chunk_offset(&self) -> usize { 0 }
239
240    fn ll_message_chunk_data(&self) -> &[i8] { &self.read_buffer_sizes_data }
241
242    fn get_result(&self) -> QueueConfigurationResult {
243        QueueConfigurationResult {
244            write_buffer_size: self.write_buffer_size,
245            write_buffer_timeout: self.write_buffer_timeout,
246            write_backlog_size: self.write_backlog_size,
247            read_backlog_size: self.read_backlog_size,
248        }
249    }
250}
251
252#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
253pub struct ReadFilterConfiguration {
254    pub filter_mode: u8,
255    pub filter_mask: u32,
256    pub filter_identifier: u32,
257}
258impl FromByteSlice for ReadFilterConfiguration {
259    fn bytes_expected() -> usize { 9 }
260    fn from_le_byte_slice(bytes: &[u8]) -> ReadFilterConfiguration {
261        ReadFilterConfiguration {
262            filter_mode: <u8>::from_le_byte_slice(&bytes[0..1]),
263            filter_mask: <u32>::from_le_byte_slice(&bytes[1..5]),
264            filter_identifier: <u32>::from_le_byte_slice(&bytes[5..9]),
265        }
266    }
267}
268
269#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
270pub struct ErrorLogLowLevel {
271    pub transceiver_state: u8,
272    pub transceiver_write_error_level: u8,
273    pub transceiver_read_error_level: u8,
274    pub transceiver_stuffing_error_count: u32,
275    pub transceiver_format_error_count: u32,
276    pub transceiver_ack_error_count: u32,
277    pub transceiver_bit1_error_count: u32,
278    pub transceiver_bit0_error_count: u32,
279    pub transceiver_crc_error_count: u32,
280    pub write_buffer_timeout_error_count: u32,
281    pub read_buffer_overflow_error_count: u32,
282    pub read_buffer_overflow_error_occurred_length: u8,
283    pub read_buffer_overflow_error_occurred_data: [bool; 32],
284    pub read_backlog_overflow_error_count: u32,
285}
286impl FromByteSlice for ErrorLogLowLevel {
287    fn bytes_expected() -> usize { 44 }
288    fn from_le_byte_slice(bytes: &[u8]) -> ErrorLogLowLevel {
289        ErrorLogLowLevel {
290            transceiver_state: <u8>::from_le_byte_slice(&bytes[0..1]),
291            transceiver_write_error_level: <u8>::from_le_byte_slice(&bytes[1..2]),
292            transceiver_read_error_level: <u8>::from_le_byte_slice(&bytes[2..3]),
293            transceiver_stuffing_error_count: <u32>::from_le_byte_slice(&bytes[3..7]),
294            transceiver_format_error_count: <u32>::from_le_byte_slice(&bytes[7..11]),
295            transceiver_ack_error_count: <u32>::from_le_byte_slice(&bytes[11..15]),
296            transceiver_bit1_error_count: <u32>::from_le_byte_slice(&bytes[15..19]),
297            transceiver_bit0_error_count: <u32>::from_le_byte_slice(&bytes[19..23]),
298            transceiver_crc_error_count: <u32>::from_le_byte_slice(&bytes[23..27]),
299            write_buffer_timeout_error_count: <u32>::from_le_byte_slice(&bytes[27..31]),
300            read_buffer_overflow_error_count: <u32>::from_le_byte_slice(&bytes[31..35]),
301            read_buffer_overflow_error_occurred_length: <u8>::from_le_byte_slice(&bytes[35..36]),
302            read_buffer_overflow_error_occurred_data: <[bool; 32]>::from_le_byte_slice(&bytes[36..40]),
303            read_backlog_overflow_error_count: <u32>::from_le_byte_slice(&bytes[40..44]),
304        }
305    }
306}
307impl LowLevelRead<bool, ErrorLogResult> for ErrorLogLowLevel {
308    fn ll_message_length(&self) -> usize { self.read_buffer_overflow_error_occurred_length as usize }
309
310    fn ll_message_chunk_offset(&self) -> usize { 0 }
311
312    fn ll_message_chunk_data(&self) -> &[bool] { &self.read_buffer_overflow_error_occurred_data }
313
314    fn get_result(&self) -> ErrorLogResult {
315        ErrorLogResult {
316            transceiver_state: self.transceiver_state,
317            transceiver_write_error_level: self.transceiver_write_error_level,
318            transceiver_read_error_level: self.transceiver_read_error_level,
319            transceiver_stuffing_error_count: self.transceiver_stuffing_error_count,
320            transceiver_format_error_count: self.transceiver_format_error_count,
321            transceiver_ack_error_count: self.transceiver_ack_error_count,
322            transceiver_bit1_error_count: self.transceiver_bit1_error_count,
323            transceiver_bit0_error_count: self.transceiver_bit0_error_count,
324            transceiver_crc_error_count: self.transceiver_crc_error_count,
325            write_buffer_timeout_error_count: self.write_buffer_timeout_error_count,
326            read_buffer_overflow_error_count: self.read_buffer_overflow_error_count,
327            read_backlog_overflow_error_count: self.read_backlog_overflow_error_count,
328        }
329    }
330}
331
332#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
333pub struct FrameReadLowLevelEvent {
334    pub frame_type: u8,
335    pub identifier: u32,
336    pub data_length: u8,
337    pub data_data: [u8; 15],
338}
339impl FromByteSlice for FrameReadLowLevelEvent {
340    fn bytes_expected() -> usize { 21 }
341    fn from_le_byte_slice(bytes: &[u8]) -> FrameReadLowLevelEvent {
342        FrameReadLowLevelEvent {
343            frame_type: <u8>::from_le_byte_slice(&bytes[0..1]),
344            identifier: <u32>::from_le_byte_slice(&bytes[1..5]),
345            data_length: <u8>::from_le_byte_slice(&bytes[5..6]),
346            data_data: <[u8; 15]>::from_le_byte_slice(&bytes[6..21]),
347        }
348    }
349}
350impl LowLevelRead<u8, FrameReadResult> for FrameReadLowLevelEvent {
351    fn ll_message_length(&self) -> usize { self.data_length as usize }
352
353    fn ll_message_chunk_offset(&self) -> usize { 0 }
354
355    fn ll_message_chunk_data(&self) -> &[u8] { &self.data_data }
356
357    fn get_result(&self) -> FrameReadResult { FrameReadResult { frame_type: self.frame_type, identifier: self.identifier } }
358}
359
360#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
361pub struct SpitfpErrorCount {
362    pub error_count_ack_checksum: u32,
363    pub error_count_message_checksum: u32,
364    pub error_count_frame: u32,
365    pub error_count_overflow: u32,
366}
367impl FromByteSlice for SpitfpErrorCount {
368    fn bytes_expected() -> usize { 16 }
369    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
370        SpitfpErrorCount {
371            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
372            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
373            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
374            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
375        }
376    }
377}
378
379#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
380pub struct Identity {
381    pub uid: String,
382    pub connected_uid: String,
383    pub position: char,
384    pub hardware_version: [u8; 3],
385    pub firmware_version: [u8; 3],
386    pub device_identifier: u16,
387}
388impl FromByteSlice for Identity {
389    fn bytes_expected() -> usize { 25 }
390    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
391        Identity {
392            uid: <String>::from_le_byte_slice(&bytes[0..8]),
393            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
394            position: <char>::from_le_byte_slice(&bytes[16..17]),
395            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
396            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
397            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
398        }
399    }
400}
401
402#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
403pub struct WriteFrameResult {
404    pub success: bool,
405}
406
407#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
408pub struct ReadFrameResult {
409    pub success: bool,
410    pub frame_type: u8,
411    pub identifier: u32,
412}
413
414#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
415pub struct SetQueueConfigurationResult {}
416
417#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
418pub struct QueueConfigurationResult {
419    pub write_buffer_size: u8,
420    pub write_buffer_timeout: i32,
421    pub write_backlog_size: u16,
422    pub read_backlog_size: u16,
423}
424
425#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
426pub struct ErrorLogResult {
427    pub transceiver_state: u8,
428    pub transceiver_write_error_level: u8,
429    pub transceiver_read_error_level: u8,
430    pub transceiver_stuffing_error_count: u32,
431    pub transceiver_format_error_count: u32,
432    pub transceiver_ack_error_count: u32,
433    pub transceiver_bit1_error_count: u32,
434    pub transceiver_bit0_error_count: u32,
435    pub transceiver_crc_error_count: u32,
436    pub write_buffer_timeout_error_count: u32,
437    pub read_buffer_overflow_error_count: u32,
438    pub read_backlog_overflow_error_count: u32,
439}
440
441#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
442pub struct FrameReadResult {
443    pub frame_type: u8,
444    pub identifier: u32,
445}
446
447/// Communicates with CAN bus devices
448#[derive(Clone)]
449pub struct CanV2Bricklet {
450    device: Device,
451}
452impl CanV2Bricklet {
453    pub const DEVICE_IDENTIFIER: u16 = 2107;
454    pub const DEVICE_DISPLAY_NAME: &'static str = "CAN Bricklet 2.0";
455    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
456    pub fn new<T: GetRequestSender>(uid: &str, req_sender: T) -> CanV2Bricklet {
457        let mut result = CanV2Bricklet { device: Device::new([2, 0, 1], uid, req_sender, 6) };
458        result.device.response_expected[u8::from(CanV2BrickletFunction::WriteFrameLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
459        result.device.response_expected[u8::from(CanV2BrickletFunction::ReadFrameLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
460        result.device.response_expected[u8::from(CanV2BrickletFunction::SetFrameReadCallbackConfiguration) as usize] =
461            ResponseExpectedFlag::True;
462        result.device.response_expected[u8::from(CanV2BrickletFunction::GetFrameReadCallbackConfiguration) as usize] =
463            ResponseExpectedFlag::AlwaysTrue;
464        result.device.response_expected[u8::from(CanV2BrickletFunction::SetTransceiverConfiguration) as usize] =
465            ResponseExpectedFlag::False;
466        result.device.response_expected[u8::from(CanV2BrickletFunction::GetTransceiverConfiguration) as usize] =
467            ResponseExpectedFlag::AlwaysTrue;
468        result.device.response_expected[u8::from(CanV2BrickletFunction::SetQueueConfigurationLowLevel) as usize] =
469            ResponseExpectedFlag::True;
470        result.device.response_expected[u8::from(CanV2BrickletFunction::GetQueueConfigurationLowLevel) as usize] =
471            ResponseExpectedFlag::AlwaysTrue;
472        result.device.response_expected[u8::from(CanV2BrickletFunction::SetReadFilterConfiguration) as usize] = ResponseExpectedFlag::False;
473        result.device.response_expected[u8::from(CanV2BrickletFunction::GetReadFilterConfiguration) as usize] =
474            ResponseExpectedFlag::AlwaysTrue;
475        result.device.response_expected[u8::from(CanV2BrickletFunction::GetErrorLogLowLevel) as usize] = ResponseExpectedFlag::AlwaysTrue;
476        result.device.response_expected[u8::from(CanV2BrickletFunction::SetCommunicationLedConfig) as usize] = ResponseExpectedFlag::False;
477        result.device.response_expected[u8::from(CanV2BrickletFunction::GetCommunicationLedConfig) as usize] =
478            ResponseExpectedFlag::AlwaysTrue;
479        result.device.response_expected[u8::from(CanV2BrickletFunction::SetErrorLedConfig) as usize] = ResponseExpectedFlag::False;
480        result.device.response_expected[u8::from(CanV2BrickletFunction::GetErrorLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
481        result.device.response_expected[u8::from(CanV2BrickletFunction::SetFrameReadableCallbackConfiguration) as usize] =
482            ResponseExpectedFlag::True;
483        result.device.response_expected[u8::from(CanV2BrickletFunction::GetFrameReadableCallbackConfiguration) as usize] =
484            ResponseExpectedFlag::AlwaysTrue;
485        result.device.response_expected[u8::from(CanV2BrickletFunction::SetErrorOccurredCallbackConfiguration) as usize] =
486            ResponseExpectedFlag::True;
487        result.device.response_expected[u8::from(CanV2BrickletFunction::GetErrorOccurredCallbackConfiguration) as usize] =
488            ResponseExpectedFlag::AlwaysTrue;
489        result.device.response_expected[u8::from(CanV2BrickletFunction::GetSpitfpErrorCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
490        result.device.response_expected[u8::from(CanV2BrickletFunction::SetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
491        result.device.response_expected[u8::from(CanV2BrickletFunction::GetBootloaderMode) as usize] = ResponseExpectedFlag::AlwaysTrue;
492        result.device.response_expected[u8::from(CanV2BrickletFunction::SetWriteFirmwarePointer) as usize] = ResponseExpectedFlag::False;
493        result.device.response_expected[u8::from(CanV2BrickletFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
494        result.device.response_expected[u8::from(CanV2BrickletFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
495        result.device.response_expected[u8::from(CanV2BrickletFunction::GetStatusLedConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
496        result.device.response_expected[u8::from(CanV2BrickletFunction::GetChipTemperature) as usize] = ResponseExpectedFlag::AlwaysTrue;
497        result.device.response_expected[u8::from(CanV2BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
498        result.device.response_expected[u8::from(CanV2BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
499        result.device.response_expected[u8::from(CanV2BrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
500        result.device.response_expected[u8::from(CanV2BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
501        result
502    }
503
504    /// Returns the response expected flag for the function specified by the function ID parameter.
505    /// It is true if the function is expected to send a response, false otherwise.
506    ///
507    /// For getter functions this is enabled by default and cannot be disabled, because those
508    /// functions will always send a response. For callback configuration functions it is enabled
509    /// by default too, but can be disabled by [`set_response_expected`](crate::can_v2_bricklet::CanV2Bricklet::set_response_expected).
510    /// For setter functions it is disabled by default and can be enabled.
511    ///
512    /// Enabling the response expected flag for a setter function allows to detect timeouts
513    /// and other error conditions calls of this setter as well. The device will then send a response
514    /// for this purpose. If this flag is disabled for a setter function then no response is sent
515    /// and errors are silently ignored, because they cannot be detected.
516    ///
517    /// See [`set_response_expected`](crate::can_v2_bricklet::CanV2Bricklet::set_response_expected) for the list of function ID constants available for this function.
518    pub fn get_response_expected(&mut self, fun: CanV2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
519        self.device.get_response_expected(u8::from(fun))
520    }
521
522    /// Changes the response expected flag of the function specified by the function ID parameter.
523    /// This flag can only be changed for setter (default value: false) and callback configuration
524    /// functions (default value: true). For getter functions it is always enabled.
525    ///
526    /// Enabling the response expected flag for a setter function allows to detect timeouts and
527    /// other error conditions calls of this setter as well. The device will then send a response
528    /// for this purpose. If this flag is disabled for a setter function then no response is sent
529    /// and errors are silently ignored, because they cannot be detected.
530    pub fn set_response_expected(&mut self, fun: CanV2BrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
531        self.device.set_response_expected(u8::from(fun), response_expected)
532    }
533
534    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
535    pub fn set_response_expected_all(&mut self, response_expected: bool) { self.device.set_response_expected_all(response_expected) }
536
537    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
538    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
539    pub fn get_api_version(&self) -> [u8; 3] { self.device.api_version }
540
541    /// See [`get_frame_read_callback_receiver`](crate::can_v2::CANV2::get_frame_read_callback_receiver)
542    pub fn get_frame_read_low_level_callback_receiver(&self) -> ConvertingCallbackReceiver<FrameReadLowLevelEvent> {
543        self.device.get_callback_receiver(u8::from(CanV2BrickletFunction::CallbackFrameReadLowLevel))
544    }
545
546    /// This receiver is triggered if a data or remote frame was received by the CAN
547    /// transceiver.
548    ///
549    /// The ``identifier`` return value follows the identifier format described for
550    /// [`write_frame`].
551    ///
552    /// For details on the ``data`` return value see [`read_frame`].
553    ///
554    /// A configurable read filter can be used to define which frames should be
555    /// received by the CAN transceiver and put into the read queue (see
556    /// [`set_read_filter_configuration`]).
557    ///
558    /// To enable this receiver, use [`set_frame_read_callback_configuration`].
559    ///
560    /// [`write_frame`]: #method.write_frame
561    /// [`read_frame`]: #method.read_frame
562    /// [`set_frame_read_callback_configuration`]: #method.set_frame_read_callback_configuration
563    /// [`set_read_filter_configuration`]: #method.set_read_filter_configuration
564    pub fn get_frame_read_callback_receiver(&self) -> ConvertingHighLevelCallbackReceiver<u8, FrameReadResult, FrameReadLowLevelEvent> {
565        ConvertingHighLevelCallbackReceiver::new(
566            self.device.get_callback_receiver(u8::from(CanV2BrickletFunction::CallbackFrameReadLowLevel)),
567        )
568    }
569
570    /// This receiver is triggered if a data or remote frame was received by the CAN
571    /// transceiver. The received frame can be read with [`read_frame`].
572    /// If additional frames are received, but [`read_frame`] was not called yet, the receiver
573    /// will not trigger again.
574    ///
575    /// A configurable read filter can be used to define which frames should be
576    /// received by the CAN transceiver and put into the read queue (see
577    /// [`set_read_filter_configuration`]).
578    ///
579    /// To enable this receiver, use [`set_frame_readable_callback_configuration`].
580    ///
581    ///
582    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
583    pub fn get_frame_readable_callback_receiver(&self) -> ConvertingCallbackReceiver<()> {
584        self.device.get_callback_receiver(u8::from(CanV2BrickletFunction::CallbackFrameReadable))
585    }
586
587    /// This receiver is triggered if any error occurred while writing, reading or transmitting CAN frames.
588    ///
589    /// The receiver is only triggered once until [`get_error_log`] is called. That function will return
590    /// details abount the error(s) occurred.
591    ///
592    /// To enable this receiver, use [`set_error_occurred_callback_configuration`].
593    ///
594    ///
595    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
596    pub fn get_error_occurred_callback_receiver(&self) -> ConvertingCallbackReceiver<()> {
597        self.device.get_callback_receiver(u8::from(CanV2BrickletFunction::CallbackErrorOccurred))
598    }
599
600    /// Writes a data or remote frame to the write queue to be transmitted over the
601    /// CAN transceiver.
602    ///
603    /// The Bricklet supports the standard 11-bit (CAN 2.0A) and the additional extended
604    /// 29-bit (CAN 2.0B) identifiers. For standard frames the Bricklet uses bit 0 to 10
605    /// from the ``identifier`` parameter as standard 11-bit identifier. For extended
606    /// frames the Bricklet uses bit 0 to 28 from the ``identifier`` parameter as
607    /// extended 29-bit identifier.
608    ///
609    /// The ``data`` parameter can be up to 15 bytes long. For data frames up to 8 bytes
610    /// will be used as the actual data. The length (DLC) field in the data or remote
611    /// frame will be set to the actual length of the ``data`` parameter. This allows
612    /// to transmit data and remote frames with excess length. For remote frames only
613    /// the length of the ``data`` parameter is used. The actual ``data`` bytes are
614    /// ignored.
615    ///
616    /// Returns *true* if the frame was successfully added to the write queue. Returns
617    /// *false* if the frame could not be added because write queue is already full or
618    /// because the write buffer or the write backlog are configured with a size of
619    /// zero (see [`set_queue_configuration`]).
620    ///
621    /// The write queue can overflow if frames are written to it at a higher rate
622    /// than the Bricklet can transmitted them over the CAN transceiver. This may
623    /// happen if the CAN transceiver is configured as read-only or is using a low baud
624    /// rate (see [`set_transceiver_configuration`]). It can also happen if the CAN
625    /// bus is congested and the frame cannot be transmitted because it constantly loses
626    /// arbitration or because the CAN transceiver is currently disabled due to a high
627    /// write error level (see [`get_error_log`]).
628    ///
629    /// Associated constants:
630    /// * CAN_V2_BRICKLET_FRAME_TYPE_STANDARD_DATA
631    ///	* CAN_V2_BRICKLET_FRAME_TYPE_STANDARD_REMOTE
632    ///	* CAN_V2_BRICKLET_FRAME_TYPE_EXTENDED_DATA
633    ///	* CAN_V2_BRICKLET_FRAME_TYPE_EXTENDED_REMOTE
634    pub fn write_frame_low_level(
635        &self,
636        frame_type: u8,
637        identifier: u32,
638        data_length: u8,
639        data_data: [u8; 15],
640    ) -> ConvertingReceiver<WriteFrameLowLevel> {
641        let mut payload = vec![0; 21];
642        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(frame_type));
643        payload[1..5].copy_from_slice(&<u32>::to_le_byte_vec(identifier));
644        payload[5..6].copy_from_slice(&<u8>::to_le_byte_vec(data_length));
645        payload[6..21].copy_from_slice(&<[u8; 15]>::to_le_byte_vec(data_data));
646
647        self.device.get(u8::from(CanV2BrickletFunction::WriteFrameLowLevel), payload)
648    }
649
650    /// Writes a data or remote frame to the write queue to be transmitted over the
651    /// CAN transceiver.
652    ///
653    /// The Bricklet supports the standard 11-bit (CAN 2.0A) and the additional extended
654    /// 29-bit (CAN 2.0B) identifiers. For standard frames the Bricklet uses bit 0 to 10
655    /// from the ``identifier`` parameter as standard 11-bit identifier. For extended
656    /// frames the Bricklet uses bit 0 to 28 from the ``identifier`` parameter as
657    /// extended 29-bit identifier.
658    ///
659    /// The ``data`` parameter can be up to 15 bytes long. For data frames up to 8 bytes
660    /// will be used as the actual data. The length (DLC) field in the data or remote
661    /// frame will be set to the actual length of the ``data`` parameter. This allows
662    /// to transmit data and remote frames with excess length. For remote frames only
663    /// the length of the ``data`` parameter is used. The actual ``data`` bytes are
664    /// ignored.
665    ///
666    /// Returns *true* if the frame was successfully added to the write queue. Returns
667    /// *false* if the frame could not be added because write queue is already full or
668    /// because the write buffer or the write backlog are configured with a size of
669    /// zero (see [`set_queue_configuration`]).
670    ///
671    /// The write queue can overflow if frames are written to it at a higher rate
672    /// than the Bricklet can transmitted them over the CAN transceiver. This may
673    /// happen if the CAN transceiver is configured as read-only or is using a low baud
674    /// rate (see [`set_transceiver_configuration`]). It can also happen if the CAN
675    /// bus is congested and the frame cannot be transmitted because it constantly loses
676    /// arbitration or because the CAN transceiver is currently disabled due to a high
677    /// write error level (see [`get_error_log`]).
678    pub fn write_frame(&self, frame_type: u8, identifier: u32, data: &[u8]) -> Result<bool, BrickletRecvTimeoutError> {
679        let ll_result = self.device.set_high_level(0, data, 15, 15, &mut |length: usize, _chunk_offset: usize, chunk: &[u8]| {
680            let chunk_length = chunk.len() as u16;
681            let mut chunk_array = [<u8>::default(); 15];
682            chunk_array[0..chunk_length as usize].copy_from_slice(&chunk);
683
684            self.write_frame_low_level(frame_type, identifier, length as u8, chunk_array).recv()
685        })?;
686        Ok(ll_result.1.success)
687    }
688
689    /// Tries to read the next data or remote frame from the read queue and returns it.
690    /// If a frame was successfully read, then the ``success`` return value is set to
691    /// *true* and the other return values contain the frame. If the read queue is
692    /// empty and no frame could be read, then the ``success`` return value is set to
693    /// *false* and the other return values contain invalid data.
694    ///
695    /// The ``identifier`` return value follows the identifier format described for
696    /// [`write_frame`].
697    ///
698    /// The ``data`` return value can be up to 15 bytes long. For data frames up to the
699    /// first 8 bytes are the actual received data. All bytes after the 8th byte are
700    /// always zero and only there to indicate the length of a data or remote frame
701    /// with excess length. For remote frames the length of the ``data`` return value
702    /// represents the requested length. The actual ``data`` bytes are always zero.
703    ///
704    /// A configurable read filter can be used to define which frames should be
705    /// received by the CAN transceiver and put into the read queue (see
706    /// [`set_read_filter_configuration`]).
707    ///
708    /// Instead of polling with this function, you can also use receivers. See the
709    /// [`set_frame_read_callback_configuration`] function and the [`get_frame_read_callback_receiver`]
710    /// callback.
711    ///
712    /// Associated constants:
713    /// * CAN_V2_BRICKLET_FRAME_TYPE_STANDARD_DATA
714    ///	* CAN_V2_BRICKLET_FRAME_TYPE_STANDARD_REMOTE
715    ///	* CAN_V2_BRICKLET_FRAME_TYPE_EXTENDED_DATA
716    ///	* CAN_V2_BRICKLET_FRAME_TYPE_EXTENDED_REMOTE
717    pub fn read_frame_low_level(&self) -> ConvertingReceiver<ReadFrameLowLevel> {
718        let payload = vec![0; 0];
719
720        self.device.get(u8::from(CanV2BrickletFunction::ReadFrameLowLevel), payload)
721    }
722
723    /// Tries to read the next data or remote frame from the read queue and returns it.
724    /// If a frame was successfully read, then the ``success`` return value is set to
725    /// *true* and the other return values contain the frame. If the read queue is
726    /// empty and no frame could be read, then the ``success`` return value is set to
727    /// *false* and the other return values contain invalid data.
728    ///
729    /// The ``identifier`` return value follows the identifier format described for
730    /// [`write_frame`].
731    ///
732    /// The ``data`` return value can be up to 15 bytes long. For data frames up to the
733    /// first 8 bytes are the actual received data. All bytes after the 8th byte are
734    /// always zero and only there to indicate the length of a data or remote frame
735    /// with excess length. For remote frames the length of the ``data`` return value
736    /// represents the requested length. The actual ``data`` bytes are always zero.
737    ///
738    /// A configurable read filter can be used to define which frames should be
739    /// received by the CAN transceiver and put into the read queue (see
740    /// [`set_read_filter_configuration`]).
741    ///
742    /// Instead of polling with this function, you can also use receivers. See the
743    /// [`set_frame_read_callback_configuration`] function and the [`get_frame_read_callback_receiver`]
744    /// callback.
745    pub fn read_frame(&self) -> Result<(Vec<u8>, ReadFrameResult), BrickletRecvTimeoutError> {
746        let ll_result = self.device.get_high_level(1, &mut || self.read_frame_low_level().recv())?;
747        Ok((ll_result.0, ll_result.1))
748    }
749
750    /// Enables and disables the [`get_frame_read_callback_receiver`] receiver.
751    ///
752    /// By default the receiver is disabled. Enabling this receiver will disable the [`get_frame_readable_callback_receiver`] receiver.
753    pub fn set_frame_read_callback_configuration(&self, enabled: bool) -> ConvertingReceiver<()> {
754        let mut payload = vec![0; 1];
755        payload[0..1].copy_from_slice(&<bool>::to_le_byte_vec(enabled));
756
757        self.device.set(u8::from(CanV2BrickletFunction::SetFrameReadCallbackConfiguration), payload)
758    }
759
760    /// Returns *true* if the [`get_frame_read_callback_receiver`] receiver is enabled, *false* otherwise.
761    pub fn get_frame_read_callback_configuration(&self) -> ConvertingReceiver<bool> {
762        let payload = vec![0; 0];
763
764        self.device.get(u8::from(CanV2BrickletFunction::GetFrameReadCallbackConfiguration), payload)
765    }
766
767    /// Sets the transceiver configuration for the CAN bus communication.
768    ///
769    /// The CAN transceiver has three different modes:
770    ///
771    /// * Normal: Reads from and writes to the CAN bus and performs active bus
772    ///   error detection and acknowledgement.
773    /// * Loopback: All reads and writes are performed internally. The transceiver
774    ///   is disconnected from the actual CAN bus.
775    /// * Read-Only: Only reads from the CAN bus, but does neither active bus error
776    ///   detection nor acknowledgement. Only the receiving part of the transceiver
777    ///   is connected to the CAN bus.
778    ///
779    /// Associated constants:
780    /// * CAN_V2_BRICKLET_TRANSCEIVER_MODE_NORMAL
781    ///	* CAN_V2_BRICKLET_TRANSCEIVER_MODE_LOOPBACK
782    ///	* CAN_V2_BRICKLET_TRANSCEIVER_MODE_READ_ONLY
783    pub fn set_transceiver_configuration(&self, baud_rate: u32, sample_point: u16, transceiver_mode: u8) -> ConvertingReceiver<()> {
784        let mut payload = vec![0; 7];
785        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(baud_rate));
786        payload[4..6].copy_from_slice(&<u16>::to_le_byte_vec(sample_point));
787        payload[6..7].copy_from_slice(&<u8>::to_le_byte_vec(transceiver_mode));
788
789        self.device.set(u8::from(CanV2BrickletFunction::SetTransceiverConfiguration), payload)
790    }
791
792    /// Returns the configuration as set by [`set_transceiver_configuration`].
793    ///
794    /// Associated constants:
795    /// * CAN_V2_BRICKLET_TRANSCEIVER_MODE_NORMAL
796    ///	* CAN_V2_BRICKLET_TRANSCEIVER_MODE_LOOPBACK
797    ///	* CAN_V2_BRICKLET_TRANSCEIVER_MODE_READ_ONLY
798    pub fn get_transceiver_configuration(&self) -> ConvertingReceiver<TransceiverConfiguration> {
799        let payload = vec![0; 0];
800
801        self.device.get(u8::from(CanV2BrickletFunction::GetTransceiverConfiguration), payload)
802    }
803
804    /// Sets the write and read queue configuration.
805    ///
806    /// The CAN transceiver has 32 buffers in total in hardware for transmitting and
807    /// receiving frames. Additionally, the Bricklet has a backlog for 768 frames in
808    /// total in software. The buffers and the backlog can be freely assigned to the
809    /// write and read queues.
810    ///
811    /// [`write_frame`] writes a frame into the write backlog. The Bricklet moves
812    /// the frame from the backlog into a free write buffer. The CAN transceiver then
813    /// transmits the frame from the write buffer to the CAN bus. If there are no
814    /// write buffers (``write_buffer_size`` is zero) or there is no write backlog
815    /// (``write_backlog_size`` is zero) then no frames can be transmitted and
816    /// [`write_frame`] returns always *false*.
817    ///
818    /// The CAN transceiver receives a frame from the CAN bus and stores it into a
819    /// free read buffer. The Bricklet moves the frame from the read buffer into the
820    /// read backlog. [`read_frame`] reads the frame from the read backlog and
821    /// returns it. If there are no read buffers (``read_buffer_sizes`` is empty) or
822    /// there is no read backlog (``read_backlog_size`` is zero) then no frames can be
823    /// received and [`read_frame`] returns always *false*.
824    ///
825    /// There can be multiple read buffers, because the CAN transceiver cannot receive
826    /// data and remote frames into the same read buffer. A positive read buffer size
827    /// represents a data frame read buffer and a negative read buffer size represents
828    /// a remote frame read buffer. A read buffer size of zero is not allowed. By
829    /// default the first read buffer is configured for data frames and the second read
830    /// buffer is configured for remote frame. There can be up to 32 different read
831    /// buffers, assuming that no write buffer is used. Each read buffer has its own
832    /// filter configuration (see [`set_read_filter_configuration`]).
833    ///
834    /// A valid queue configuration fulfills these conditions::
835    ///
836    ///  write_buffer_size + abs(read_buffer_size_0) + abs(read_buffer_size_1) + ... + abs(read_buffer_size_31) <= 32
837    ///  write_backlog_size + read_backlog_size <= 768
838    ///
839    /// The write buffer timeout has three different modes that define how a failed
840    /// frame transmission should be handled:
841    ///
842    /// * Single-Shot (< 0): Only one transmission attempt will be made. If the
843    ///   transmission fails then the frame is discarded.
844    /// * Infinite (= 0): Infinite transmission attempts will be made. The frame will
845    ///   never be discarded.
846    /// * Milliseconds (> 0): A limited number of transmission attempts will be made.
847    ///   If the frame could not be transmitted successfully after the configured
848    ///   number of milliseconds then the frame is discarded.
849    ///
850    /// The current content of the queues is lost when this function is called.
851    pub fn set_queue_configuration_low_level(
852        &self,
853        write_buffer_size: u8,
854        write_buffer_timeout: i32,
855        write_backlog_size: u16,
856        read_buffer_sizes_length: u8,
857        read_buffer_sizes_data: [i8; 32],
858        read_backlog_size: u16,
859    ) -> ConvertingReceiver<SetQueueConfigurationLowLevel> {
860        let mut payload = vec![0; 42];
861        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(write_buffer_size));
862        payload[1..5].copy_from_slice(&<i32>::to_le_byte_vec(write_buffer_timeout));
863        payload[5..7].copy_from_slice(&<u16>::to_le_byte_vec(write_backlog_size));
864        payload[7..8].copy_from_slice(&<u8>::to_le_byte_vec(read_buffer_sizes_length));
865        payload[8..40].copy_from_slice(&<[i8; 32]>::to_le_byte_vec(read_buffer_sizes_data));
866        payload[40..42].copy_from_slice(&<u16>::to_le_byte_vec(read_backlog_size));
867
868        self.device.set(u8::from(CanV2BrickletFunction::SetQueueConfigurationLowLevel), payload)
869    }
870
871    /// Sets the write and read queue configuration.
872    ///
873    /// The CAN transceiver has 32 buffers in total in hardware for transmitting and
874    /// receiving frames. Additionally, the Bricklet has a backlog for 768 frames in
875    /// total in software. The buffers and the backlog can be freely assigned to the
876    /// write and read queues.
877    ///
878    /// [`write_frame`] writes a frame into the write backlog. The Bricklet moves
879    /// the frame from the backlog into a free write buffer. The CAN transceiver then
880    /// transmits the frame from the write buffer to the CAN bus. If there are no
881    /// write buffers (``write_buffer_size`` is zero) or there is no write backlog
882    /// (``write_backlog_size`` is zero) then no frames can be transmitted and
883    /// [`write_frame`] returns always *false*.
884    ///
885    /// The CAN transceiver receives a frame from the CAN bus and stores it into a
886    /// free read buffer. The Bricklet moves the frame from the read buffer into the
887    /// read backlog. [`read_frame`] reads the frame from the read backlog and
888    /// returns it. If there are no read buffers (``read_buffer_sizes`` is empty) or
889    /// there is no read backlog (``read_backlog_size`` is zero) then no frames can be
890    /// received and [`read_frame`] returns always *false*.
891    ///
892    /// There can be multiple read buffers, because the CAN transceiver cannot receive
893    /// data and remote frames into the same read buffer. A positive read buffer size
894    /// represents a data frame read buffer and a negative read buffer size represents
895    /// a remote frame read buffer. A read buffer size of zero is not allowed. By
896    /// default the first read buffer is configured for data frames and the second read
897    /// buffer is configured for remote frame. There can be up to 32 different read
898    /// buffers, assuming that no write buffer is used. Each read buffer has its own
899    /// filter configuration (see [`set_read_filter_configuration`]).
900    ///
901    /// A valid queue configuration fulfills these conditions::
902    ///
903    ///  write_buffer_size + abs(read_buffer_size_0) + abs(read_buffer_size_1) + ... + abs(read_buffer_size_31) <= 32
904    ///  write_backlog_size + read_backlog_size <= 768
905    ///
906    /// The write buffer timeout has three different modes that define how a failed
907    /// frame transmission should be handled:
908    ///
909    /// * Single-Shot (< 0): Only one transmission attempt will be made. If the
910    ///   transmission fails then the frame is discarded.
911    /// * Infinite (= 0): Infinite transmission attempts will be made. The frame will
912    ///   never be discarded.
913    /// * Milliseconds (> 0): A limited number of transmission attempts will be made.
914    ///   If the frame could not be transmitted successfully after the configured
915    ///   number of milliseconds then the frame is discarded.
916    ///
917    /// The current content of the queues is lost when this function is called.
918    pub fn set_queue_configuration(
919        &self,
920        write_buffer_size: u8,
921        write_buffer_timeout: i32,
922        write_backlog_size: u16,
923        read_backlog_size: u16,
924        read_buffer_sizes: &[i8],
925    ) -> Result<(), BrickletRecvTimeoutError> {
926        let _ll_result =
927            self.device.set_high_level(2, read_buffer_sizes, 32, 32, &mut |length: usize, _chunk_offset: usize, chunk: &[i8]| {
928                let chunk_length = chunk.len() as u16;
929                let mut chunk_array = [<i8>::default(); 32];
930                chunk_array[0..chunk_length as usize].copy_from_slice(&chunk);
931
932                let result = self
933                    .set_queue_configuration_low_level(
934                        write_buffer_size,
935                        write_buffer_timeout,
936                        write_backlog_size,
937                        length as u8,
938                        chunk_array,
939                        read_backlog_size,
940                    )
941                    .recv();
942                if let Err(BrickletRecvTimeoutError::SuccessButResponseExpectedIsDisabled) = result {
943                    Ok(Default::default())
944                } else {
945                    result
946                }
947            })?;
948        Ok(())
949    }
950
951    /// Returns the queue configuration as set by [`set_queue_configuration`].
952    pub fn get_queue_configuration_low_level(&self) -> ConvertingReceiver<QueueConfigurationLowLevel> {
953        let payload = vec![0; 0];
954
955        self.device.get(u8::from(CanV2BrickletFunction::GetQueueConfigurationLowLevel), payload)
956    }
957
958    /// Returns the queue configuration as set by [`set_queue_configuration`].
959    pub fn get_queue_configuration(&self) -> Result<(Vec<i8>, QueueConfigurationResult), BrickletRecvTimeoutError> {
960        let ll_result = self.device.get_high_level(3, &mut || self.get_queue_configuration_low_level().recv())?;
961        Ok((ll_result.0, ll_result.1))
962    }
963
964    /// Set the read filter configuration for the given read buffer index. This can be
965    /// used to define which frames should be received by the CAN transceiver and put
966    /// into the read buffer.
967    ///
968    /// The read filter has four different modes that define if and how the filter mask
969    /// and the filter identifier are applied:
970    ///
971    /// * Accept-All: All frames are received.
972    /// * Match-Standard-Only: Only standard frames with a matching identifier are
973    ///   received.
974    /// * Match-Extended-Only: Only extended frames with a matching identifier are
975    ///   received.
976    /// * Match-Standard-And-Extended: Standard and extended frames with a matching
977    ///   identifier are received.
978    ///
979    /// The filter mask and filter identifier are used as bit masks. Their usage
980    /// depends on the mode:
981    ///
982    /// * Accept-All: Mask and identifier are ignored.
983    /// * Match-Standard-Only: Bit 0 to 10 (11 bits) of filter mask and filter
984    ///   identifier are used to match the 11-bit identifier of standard frames.
985    /// * Match-Extended-Only: Bit 0 to 28 (29 bits) of filter mask and filter
986    ///   identifier are used to match the 29-bit identifier of extended frames.
987    /// * Match-Standard-And-Extended: Bit 18 to 28 (11 bits) of filter mask and filter
988    ///   identifier are used to match the 11-bit identifier of standard frames, bit 0
989    ///   to 17 (18 bits) are ignored in this case. Bit 0 to 28 (29 bits) of filter
990    ///   mask and filter identifier are used to match the 29-bit identifier of extended
991    ///   frames.
992    ///
993    /// The filter mask and filter identifier are applied in this way: The filter mask
994    /// is used to select the frame identifier bits that should be compared to the
995    /// corresponding filter identifier bits. All unselected bits are automatically
996    /// accepted. All selected bits have to match the filter identifier to be accepted.
997    /// If all bits for the selected mode are accepted then the frame is accepted and
998    /// is added to the read buffer.
999    ///
1000    ///  Filter Mask Bit| Filter Identifier Bit| Frame Identifier Bit| Result
1001    ///  --- | --- | --- | ---
1002    ///  0| X| X| Accept
1003    ///  1| 0| 0| Accept
1004    ///  1| 0| 1| Reject
1005    ///  1| 1| 0| Reject
1006    ///  1| 1| 1| Accept
1007    ///
1008    /// For example, to receive standard frames with identifier 0x123 only, the mode
1009    /// can be set to Match-Standard-Only with 0x7FF as mask and 0x123 as identifier.
1010    /// The mask of 0x7FF selects all 11 identifier bits for matching so that the
1011    /// identifier has to be exactly 0x123 to be accepted.
1012    ///
1013    /// To accept identifier 0x123 and identifier 0x456 at the same time, just set
1014    /// filter 2 to 0x456 and keep mask and filter 1 unchanged.
1015    ///
1016    /// There can be up to 32 different read filters configured at the same time,
1017    /// because there can be up to 32 read buffer (see [`set_queue_configuration`]).
1018    ///
1019    /// The default mode is accept-all for all read buffers.
1020    ///
1021    /// Associated constants:
1022    /// * CAN_V2_BRICKLET_FILTER_MODE_ACCEPT_ALL
1023    ///	* CAN_V2_BRICKLET_FILTER_MODE_MATCH_STANDARD_ONLY
1024    ///	* CAN_V2_BRICKLET_FILTER_MODE_MATCH_EXTENDED_ONLY
1025    ///	* CAN_V2_BRICKLET_FILTER_MODE_MATCH_STANDARD_AND_EXTENDED
1026    pub fn set_read_filter_configuration(
1027        &self,
1028        buffer_index: u8,
1029        filter_mode: u8,
1030        filter_mask: u32,
1031        filter_identifier: u32,
1032    ) -> ConvertingReceiver<()> {
1033        let mut payload = vec![0; 10];
1034        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(buffer_index));
1035        payload[1..2].copy_from_slice(&<u8>::to_le_byte_vec(filter_mode));
1036        payload[2..6].copy_from_slice(&<u32>::to_le_byte_vec(filter_mask));
1037        payload[6..10].copy_from_slice(&<u32>::to_le_byte_vec(filter_identifier));
1038
1039        self.device.set(u8::from(CanV2BrickletFunction::SetReadFilterConfiguration), payload)
1040    }
1041
1042    /// Returns the read filter configuration as set by [`set_read_filter_configuration`].
1043    ///
1044    /// Associated constants:
1045    /// * CAN_V2_BRICKLET_FILTER_MODE_ACCEPT_ALL
1046    ///	* CAN_V2_BRICKLET_FILTER_MODE_MATCH_STANDARD_ONLY
1047    ///	* CAN_V2_BRICKLET_FILTER_MODE_MATCH_EXTENDED_ONLY
1048    ///	* CAN_V2_BRICKLET_FILTER_MODE_MATCH_STANDARD_AND_EXTENDED
1049    pub fn get_read_filter_configuration(&self, buffer_index: u8) -> ConvertingReceiver<ReadFilterConfiguration> {
1050        let mut payload = vec![0; 1];
1051        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(buffer_index));
1052
1053        self.device.get(u8::from(CanV2BrickletFunction::GetReadFilterConfiguration), payload)
1054    }
1055
1056    /// Returns information about different kinds of errors.
1057    ///
1058    /// The write and read error levels indicate the current level of stuffing, form,
1059    /// acknowledgement, bit and checksum errors during CAN bus write and read
1060    /// operations. For each of this error kinds there is also an individual counter.
1061    ///
1062    /// When the write error level extends 255 then the CAN transceiver gets disabled
1063    /// and no frames can be transmitted or received anymore. The CAN transceiver will
1064    /// automatically be activated again after the CAN bus is idle for a while.
1065    ///
1066    /// The write buffer timeout, read buffer and backlog overflow counts represents the
1067    /// number of these errors:
1068    ///
1069    /// * A write buffer timeout occurs if a frame could not be transmitted before the
1070    ///   configured write buffer timeout expired (see [`set_queue_configuration`]).
1071    /// * A read buffer overflow occurs if a read buffer of the CAN transceiver
1072    ///   still contains the last received frame when the next frame arrives. In this
1073    ///   case the last received frame is lost. This happens if the CAN transceiver
1074    ///   receives more frames than the Bricklet can handle. Using the read filter
1075    ///   (see [`set_read_filter_configuration`]) can help to reduce the amount of
1076    ///   received frames. This count is not exact, but a lower bound, because the
1077    ///   Bricklet might not able detect all overflows if they occur in rapid succession.
1078    /// * A read backlog overflow occurs if the read backlog of the Bricklet is already
1079    ///   full when the next frame should be read from a read buffer of the CAN
1080    ///   transceiver. In this case the frame in the read buffer is lost. This
1081    ///   happens if the CAN transceiver receives more frames to be added to the read
1082    ///   backlog than are removed from the read backlog using the [`read_frame`]
1083    ///   function. Using the [`get_frame_read_callback_receiver`] receiver ensures that the read backlog
1084    ///   can not overflow.
1085    ///
1086    /// The read buffer overflow counter counts the overflows of all configured read
1087    /// buffers. Which read buffer exactly suffered from an overflow can be figured
1088    /// out from the read buffer overflow occurrence list
1089    /// (``read_buffer_overflow_error_occurred``). Reading the error log clears the
1090    /// occurence list.
1091    ///
1092    /// Associated constants:
1093    /// * CAN_V2_BRICKLET_TRANSCEIVER_STATE_ACTIVE
1094    ///	* CAN_V2_BRICKLET_TRANSCEIVER_STATE_PASSIVE
1095    ///	* CAN_V2_BRICKLET_TRANSCEIVER_STATE_DISABLED
1096    pub fn get_error_log_low_level(&self) -> ConvertingReceiver<ErrorLogLowLevel> {
1097        let payload = vec![0; 0];
1098
1099        self.device.get(u8::from(CanV2BrickletFunction::GetErrorLogLowLevel), payload)
1100    }
1101
1102    /// Returns information about different kinds of errors.
1103    ///
1104    /// The write and read error levels indicate the current level of stuffing, form,
1105    /// acknowledgement, bit and checksum errors during CAN bus write and read
1106    /// operations. For each of this error kinds there is also an individual counter.
1107    ///
1108    /// When the write error level extends 255 then the CAN transceiver gets disabled
1109    /// and no frames can be transmitted or received anymore. The CAN transceiver will
1110    /// automatically be activated again after the CAN bus is idle for a while.
1111    ///
1112    /// The write buffer timeout, read buffer and backlog overflow counts represents the
1113    /// number of these errors:
1114    ///
1115    /// * A write buffer timeout occurs if a frame could not be transmitted before the
1116    ///   configured write buffer timeout expired (see [`set_queue_configuration`]).
1117    /// * A read buffer overflow occurs if a read buffer of the CAN transceiver
1118    ///   still contains the last received frame when the next frame arrives. In this
1119    ///   case the last received frame is lost. This happens if the CAN transceiver
1120    ///   receives more frames than the Bricklet can handle. Using the read filter
1121    ///   (see [`set_read_filter_configuration`]) can help to reduce the amount of
1122    ///   received frames. This count is not exact, but a lower bound, because the
1123    ///   Bricklet might not able detect all overflows if they occur in rapid succession.
1124    /// * A read backlog overflow occurs if the read backlog of the Bricklet is already
1125    ///   full when the next frame should be read from a read buffer of the CAN
1126    ///   transceiver. In this case the frame in the read buffer is lost. This
1127    ///   happens if the CAN transceiver receives more frames to be added to the read
1128    ///   backlog than are removed from the read backlog using the [`read_frame`]
1129    ///   function. Using the [`get_frame_read_callback_receiver`] receiver ensures that the read backlog
1130    ///   can not overflow.
1131    ///
1132    /// The read buffer overflow counter counts the overflows of all configured read
1133    /// buffers. Which read buffer exactly suffered from an overflow can be figured
1134    /// out from the read buffer overflow occurrence list
1135    /// (``read_buffer_overflow_error_occurred``). Reading the error log clears the
1136    /// occurence list.
1137    pub fn get_error_log(&self) -> Result<(Vec<bool>, ErrorLogResult), BrickletRecvTimeoutError> {
1138        let ll_result = self.device.get_high_level(4, &mut || self.get_error_log_low_level().recv())?;
1139        Ok((ll_result.0, ll_result.1))
1140    }
1141
1142    /// Sets the communication LED configuration. By default the LED shows
1143    /// CAN-Bus traffic, it flickers once for every 40 transmitted or received frames.
1144    ///
1145    /// You can also turn the LED permanently on/off or show a heartbeat.
1146    ///
1147    /// If the Bricklet is in bootloader mode, the LED is off.
1148    ///
1149    /// Associated constants:
1150    /// * CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_OFF
1151    ///	* CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_ON
1152    ///	* CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT
1153    ///	* CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION
1154    pub fn set_communication_led_config(&self, config: u8) -> ConvertingReceiver<()> {
1155        let mut payload = vec![0; 1];
1156        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(config));
1157
1158        self.device.set(u8::from(CanV2BrickletFunction::SetCommunicationLedConfig), payload)
1159    }
1160
1161    /// Returns the configuration as set by [`set_communication_led_config`]
1162    ///
1163    /// Associated constants:
1164    /// * CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_OFF
1165    ///	* CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_ON
1166    ///	* CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT
1167    ///	* CAN_V2_BRICKLET_COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION
1168    pub fn get_communication_led_config(&self) -> ConvertingReceiver<u8> {
1169        let payload = vec![0; 0];
1170
1171        self.device.get(u8::from(CanV2BrickletFunction::GetCommunicationLedConfig), payload)
1172    }
1173
1174    /// Sets the error LED configuration.
1175    ///
1176    /// By default (show-transceiver-state) the error LED turns on if the CAN
1177    /// transceiver is passive or disabled state (see [`get_error_log`]). If
1178    /// the CAN transceiver is in active state the LED turns off.
1179    ///
1180    /// If the LED is configured as show-error then the error LED turns on if any error
1181    /// occurs. If you call this function with the show-error option again, the LED will
1182    /// turn off until the next error occurs.
1183    ///
1184    /// You can also turn the LED permanently on/off or show a heartbeat.
1185    ///
1186    /// If the Bricklet is in bootloader mode, the LED is off.
1187    ///
1188    /// Associated constants:
1189    /// * CAN_V2_BRICKLET_ERROR_LED_CONFIG_OFF
1190    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_ON
1191    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT
1192    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_TRANSCEIVER_STATE
1193    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR
1194    pub fn set_error_led_config(&self, config: u8) -> ConvertingReceiver<()> {
1195        let mut payload = vec![0; 1];
1196        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(config));
1197
1198        self.device.set(u8::from(CanV2BrickletFunction::SetErrorLedConfig), payload)
1199    }
1200
1201    /// Returns the configuration as set by [`set_error_led_config`].
1202    ///
1203    /// Associated constants:
1204    /// * CAN_V2_BRICKLET_ERROR_LED_CONFIG_OFF
1205    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_ON
1206    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_HEARTBEAT
1207    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_TRANSCEIVER_STATE
1208    ///	* CAN_V2_BRICKLET_ERROR_LED_CONFIG_SHOW_ERROR
1209    pub fn get_error_led_config(&self) -> ConvertingReceiver<u8> {
1210        let payload = vec![0; 0];
1211
1212        self.device.get(u8::from(CanV2BrickletFunction::GetErrorLedConfig), payload)
1213    }
1214
1215    /// Enables and disables the [`get_frame_readable_callback_receiver`] receiver.
1216    ///
1217    /// By default the receiver is disabled. Enabling this receiver will disable the [`get_frame_read_callback_receiver`] receiver.
1218    ///
1219    ///
1220    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
1221    pub fn set_frame_readable_callback_configuration(&self, enabled: bool) -> ConvertingReceiver<()> {
1222        let mut payload = vec![0; 1];
1223        payload[0..1].copy_from_slice(&<bool>::to_le_byte_vec(enabled));
1224
1225        self.device.set(u8::from(CanV2BrickletFunction::SetFrameReadableCallbackConfiguration), payload)
1226    }
1227
1228    /// Returns *true* if the [`get_frame_readable_callback_receiver`] receiver is enabled, *false* otherwise.
1229    ///
1230    ///
1231    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
1232    pub fn get_frame_readable_callback_configuration(&self) -> ConvertingReceiver<bool> {
1233        let payload = vec![0; 0];
1234
1235        self.device.get(u8::from(CanV2BrickletFunction::GetFrameReadableCallbackConfiguration), payload)
1236    }
1237
1238    /// Enables and disables the [`get_error_occurred_callback_receiver`] receiver.
1239    ///
1240    /// By default the receiver is disabled.
1241    ///
1242    ///
1243    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
1244    pub fn set_error_occurred_callback_configuration(&self, enabled: bool) -> ConvertingReceiver<()> {
1245        let mut payload = vec![0; 1];
1246        payload[0..1].copy_from_slice(&<bool>::to_le_byte_vec(enabled));
1247
1248        self.device.set(u8::from(CanV2BrickletFunction::SetErrorOccurredCallbackConfiguration), payload)
1249    }
1250
1251    /// Returns *true* if the [`get_error_occurred_callback_receiver`] receiver is enabled, *false* otherwise.
1252    ///
1253    ///
1254    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
1255    pub fn get_error_occurred_callback_configuration(&self) -> ConvertingReceiver<bool> {
1256        let payload = vec![0; 0];
1257
1258        self.device.get(u8::from(CanV2BrickletFunction::GetErrorOccurredCallbackConfiguration), payload)
1259    }
1260
1261    /// Returns the error count for the communication between Brick and Bricklet.
1262    ///
1263    /// The errors are divided into
1264    ///
1265    /// * ACK checksum errors,
1266    /// * message checksum errors,
1267    /// * framing errors and
1268    /// * overflow errors.
1269    ///
1270    /// The errors counts are for errors that occur on the Bricklet side. All
1271    /// Bricks have a similar function that returns the errors on the Brick side.
1272    pub fn get_spitfp_error_count(&self) -> ConvertingReceiver<SpitfpErrorCount> {
1273        let payload = vec![0; 0];
1274
1275        self.device.get(u8::from(CanV2BrickletFunction::GetSpitfpErrorCount), payload)
1276    }
1277
1278    /// Sets the bootloader mode and returns the status after the requested
1279    /// mode change was instigated.
1280    ///
1281    /// You can change from bootloader mode to firmware mode and vice versa. A change
1282    /// from bootloader mode to firmware mode will only take place if the entry function,
1283    /// device identifier and CRC are present and correct.
1284    ///
1285    /// This function is used by Brick Viewer during flashing. It should not be
1286    /// necessary to call it in a normal user program.
1287    ///
1288    /// Associated constants:
1289    /// * CAN_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1290    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1291    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1292    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1293    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1294    ///	* CAN_V2_BRICKLET_BOOTLOADER_STATUS_OK
1295    ///	* CAN_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
1296    ///	* CAN_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
1297    ///	* CAN_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
1298    ///	* CAN_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
1299    ///	* CAN_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
1300    pub fn set_bootloader_mode(&self, mode: u8) -> ConvertingReceiver<u8> {
1301        let mut payload = vec![0; 1];
1302        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(mode));
1303
1304        self.device.get(u8::from(CanV2BrickletFunction::SetBootloaderMode), payload)
1305    }
1306
1307    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
1308    ///
1309    /// Associated constants:
1310    /// * CAN_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
1311    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
1312    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
1313    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
1314    ///	* CAN_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
1315    pub fn get_bootloader_mode(&self) -> ConvertingReceiver<u8> {
1316        let payload = vec![0; 0];
1317
1318        self.device.get(u8::from(CanV2BrickletFunction::GetBootloaderMode), payload)
1319    }
1320
1321    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
1322    /// to be increased by chunks of size 64. The data is written to flash
1323    /// every 4 chunks (which equals to one page of size 256).
1324    ///
1325    /// This function is used by Brick Viewer during flashing. It should not be
1326    /// necessary to call it in a normal user program.
1327    pub fn set_write_firmware_pointer(&self, pointer: u32) -> ConvertingReceiver<()> {
1328        let mut payload = vec![0; 4];
1329        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(pointer));
1330
1331        self.device.set(u8::from(CanV2BrickletFunction::SetWriteFirmwarePointer), payload)
1332    }
1333
1334    /// Writes 64 Bytes of firmware at the position as written by
1335    /// [`set_write_firmware_pointer`] before. The firmware is written
1336    /// to flash every 4 chunks.
1337    ///
1338    /// You can only write firmware in bootloader mode.
1339    ///
1340    /// This function is used by Brick Viewer during flashing. It should not be
1341    /// necessary to call it in a normal user program.
1342    pub fn write_firmware(&self, data: [u8; 64]) -> ConvertingReceiver<u8> {
1343        let mut payload = vec![0; 64];
1344        payload[0..64].copy_from_slice(&<[u8; 64]>::to_le_byte_vec(data));
1345
1346        self.device.get(u8::from(CanV2BrickletFunction::WriteFirmware), payload)
1347    }
1348
1349    /// Sets the status LED configuration. By default the LED shows
1350    /// communication traffic between Brick and Bricklet, it flickers once
1351    /// for every 10 received data packets.
1352    ///
1353    /// You can also turn the LED permanently on/off or show a heartbeat.
1354    ///
1355    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
1356    ///
1357    /// Associated constants:
1358    /// * CAN_V2_BRICKLET_STATUS_LED_CONFIG_OFF
1359    ///	* CAN_V2_BRICKLET_STATUS_LED_CONFIG_ON
1360    ///	* CAN_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1361    ///	* CAN_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1362    pub fn set_status_led_config(&self, config: u8) -> ConvertingReceiver<()> {
1363        let mut payload = vec![0; 1];
1364        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(config));
1365
1366        self.device.set(u8::from(CanV2BrickletFunction::SetStatusLedConfig), payload)
1367    }
1368
1369    /// Returns the configuration as set by [`set_status_led_config`]
1370    ///
1371    /// Associated constants:
1372    /// * CAN_V2_BRICKLET_STATUS_LED_CONFIG_OFF
1373    ///	* CAN_V2_BRICKLET_STATUS_LED_CONFIG_ON
1374    ///	* CAN_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1375    ///	* CAN_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1376    pub fn get_status_led_config(&self) -> ConvertingReceiver<u8> {
1377        let payload = vec![0; 0];
1378
1379        self.device.get(u8::from(CanV2BrickletFunction::GetStatusLedConfig), payload)
1380    }
1381
1382    /// Returns the temperature as measured inside the microcontroller. The
1383    /// value returned is not the ambient temperature!
1384    ///
1385    /// The temperature is only proportional to the real temperature and it has bad
1386    /// accuracy. Practically it is only useful as an indicator for
1387    /// temperature changes.
1388    pub fn get_chip_temperature(&self) -> ConvertingReceiver<i16> {
1389        let payload = vec![0; 0];
1390
1391        self.device.get(u8::from(CanV2BrickletFunction::GetChipTemperature), payload)
1392    }
1393
1394    /// Calling this function will reset the Bricklet. All configurations
1395    /// will be lost.
1396    ///
1397    /// After a reset you have to create new device objects,
1398    /// calling functions on the existing ones will result in
1399    /// undefined behavior!
1400    pub fn reset(&self) -> ConvertingReceiver<()> {
1401        let payload = vec![0; 0];
1402
1403        self.device.set(u8::from(CanV2BrickletFunction::Reset), payload)
1404    }
1405
1406    /// Writes a new UID into flash. If you want to set a new UID
1407    /// you have to decode the Base58 encoded UID string into an
1408    /// integer first.
1409    ///
1410    /// We recommend that you use Brick Viewer to change the UID.
1411    pub fn write_uid(&self, uid: u32) -> ConvertingReceiver<()> {
1412        let mut payload = vec![0; 4];
1413        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(uid));
1414
1415        self.device.set(u8::from(CanV2BrickletFunction::WriteUid), payload)
1416    }
1417
1418    /// Returns the current UID as an integer. Encode as
1419    /// Base58 to get the usual string version.
1420    pub fn read_uid(&self) -> ConvertingReceiver<u32> {
1421        let payload = vec![0; 0];
1422
1423        self.device.get(u8::from(CanV2BrickletFunction::ReadUid), payload)
1424    }
1425
1426    /// Returns the UID, the UID where the Bricklet is connected to,
1427    /// the position, the hardware and firmware version as well as the
1428    /// device identifier.
1429    ///
1430    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
1431    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
1432    /// position 'z'.
1433    ///
1434    /// The device identifier numbers can be found [here](device_identifier).
1435    /// |device_identifier_constant|
1436    pub fn get_identity(&self) -> ConvertingReceiver<Identity> {
1437        let payload = vec![0; 0];
1438
1439        self.device.get(u8::from(CanV2BrickletFunction::GetIdentity), payload)
1440    }
1441}