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}