1use crate::{
15 byte_converter::*,
16 converting_receiver::{BrickletError, BrickletRecvTimeoutError, ConvertingReceiver},
17 device::*,
18 ip_connection::GetRequestSender,
19 low_level_traits::*,
20};
21pub enum Oled128x64V2BrickletFunction {
22 WritePixelsLowLevel,
23 ReadPixelsLowLevel,
24 ClearDisplay,
25 SetDisplayConfiguration,
26 GetDisplayConfiguration,
27 WriteLine,
28 DrawBufferedFrame,
29 GetSpitfpErrorCount,
30 SetBootloaderMode,
31 GetBootloaderMode,
32 SetWriteFirmwarePointer,
33 WriteFirmware,
34 SetStatusLedConfig,
35 GetStatusLedConfig,
36 GetChipTemperature,
37 Reset,
38 WriteUid,
39 ReadUid,
40 GetIdentity,
41}
42impl From<Oled128x64V2BrickletFunction> for u8 {
43 fn from(fun: Oled128x64V2BrickletFunction) -> Self {
44 match fun {
45 Oled128x64V2BrickletFunction::WritePixelsLowLevel => 1,
46 Oled128x64V2BrickletFunction::ReadPixelsLowLevel => 2,
47 Oled128x64V2BrickletFunction::ClearDisplay => 3,
48 Oled128x64V2BrickletFunction::SetDisplayConfiguration => 4,
49 Oled128x64V2BrickletFunction::GetDisplayConfiguration => 5,
50 Oled128x64V2BrickletFunction::WriteLine => 6,
51 Oled128x64V2BrickletFunction::DrawBufferedFrame => 7,
52 Oled128x64V2BrickletFunction::GetSpitfpErrorCount => 234,
53 Oled128x64V2BrickletFunction::SetBootloaderMode => 235,
54 Oled128x64V2BrickletFunction::GetBootloaderMode => 236,
55 Oled128x64V2BrickletFunction::SetWriteFirmwarePointer => 237,
56 Oled128x64V2BrickletFunction::WriteFirmware => 238,
57 Oled128x64V2BrickletFunction::SetStatusLedConfig => 239,
58 Oled128x64V2BrickletFunction::GetStatusLedConfig => 240,
59 Oled128x64V2BrickletFunction::GetChipTemperature => 242,
60 Oled128x64V2BrickletFunction::Reset => 243,
61 Oled128x64V2BrickletFunction::WriteUid => 248,
62 Oled128x64V2BrickletFunction::ReadUid => 249,
63 Oled128x64V2BrickletFunction::GetIdentity => 255,
64 }
65 }
66}
67pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
68pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
69pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
70pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
71pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
72pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
73pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
74pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
75pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
76pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
77pub const OLED_128X64_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
78pub const OLED_128X64_V2_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
79pub const OLED_128X64_V2_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
80pub const OLED_128X64_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
81pub const OLED_128X64_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
82
83#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
84pub struct WritePixelsLowLevel {}
85impl FromByteSlice for WritePixelsLowLevel {
86 fn bytes_expected() -> usize { 0 }
87 fn from_le_byte_slice(_bytes: &[u8]) -> WritePixelsLowLevel { WritePixelsLowLevel {} }
88}
89impl LowLevelWrite<WritePixelsResult> for WritePixelsLowLevel {
90 fn ll_message_written(&self) -> usize { 448 }
91
92 fn get_result(&self) -> WritePixelsResult { WritePixelsResult {} }
93}
94
95#[derive(Clone, Copy)]
96pub struct ReadPixelsLowLevel {
97 pub pixels_length: u16,
98 pub pixels_chunk_offset: u16,
99 pub pixels_chunk_data: [bool; 480],
100}
101impl FromByteSlice for ReadPixelsLowLevel {
102 fn bytes_expected() -> usize { 64 }
103 fn from_le_byte_slice(bytes: &[u8]) -> ReadPixelsLowLevel {
104 ReadPixelsLowLevel {
105 pixels_length: <u16>::from_le_byte_slice(&bytes[0..2]),
106 pixels_chunk_offset: <u16>::from_le_byte_slice(&bytes[2..4]),
107 pixels_chunk_data: <[bool; 480]>::from_le_byte_slice(&bytes[4..64]),
108 }
109 }
110}
111impl LowLevelRead<bool, ReadPixelsResult> for ReadPixelsLowLevel {
112 fn ll_message_length(&self) -> usize { self.pixels_length as usize }
113
114 fn ll_message_chunk_offset(&self) -> usize { self.pixels_chunk_offset as usize }
115
116 fn ll_message_chunk_data(&self) -> &[bool] { &self.pixels_chunk_data }
117
118 fn get_result(&self) -> ReadPixelsResult { ReadPixelsResult {} }
119}
120
121#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
122pub struct DisplayConfiguration {
123 pub contrast: u8,
124 pub invert: bool,
125 pub automatic_draw: bool,
126}
127impl FromByteSlice for DisplayConfiguration {
128 fn bytes_expected() -> usize { 3 }
129 fn from_le_byte_slice(bytes: &[u8]) -> DisplayConfiguration {
130 DisplayConfiguration {
131 contrast: <u8>::from_le_byte_slice(&bytes[0..1]),
132 invert: <bool>::from_le_byte_slice(&bytes[1..2]),
133 automatic_draw: <bool>::from_le_byte_slice(&bytes[2..3]),
134 }
135 }
136}
137
138#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
139pub struct SpitfpErrorCount {
140 pub error_count_ack_checksum: u32,
141 pub error_count_message_checksum: u32,
142 pub error_count_frame: u32,
143 pub error_count_overflow: u32,
144}
145impl FromByteSlice for SpitfpErrorCount {
146 fn bytes_expected() -> usize { 16 }
147 fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
148 SpitfpErrorCount {
149 error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
150 error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
151 error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
152 error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
153 }
154 }
155}
156
157#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
158pub struct Identity {
159 pub uid: String,
160 pub connected_uid: String,
161 pub position: char,
162 pub hardware_version: [u8; 3],
163 pub firmware_version: [u8; 3],
164 pub device_identifier: u16,
165}
166impl FromByteSlice for Identity {
167 fn bytes_expected() -> usize { 25 }
168 fn from_le_byte_slice(bytes: &[u8]) -> Identity {
169 Identity {
170 uid: <String>::from_le_byte_slice(&bytes[0..8]),
171 connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
172 position: <char>::from_le_byte_slice(&bytes[16..17]),
173 hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
174 firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
175 device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
176 }
177 }
178}
179
180#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
181pub struct WritePixelsResult {}
182
183#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
184pub struct ReadPixelsResult {}
185
186#[derive(Clone)]
188pub struct Oled128x64V2Bricklet {
189 device: Device,
190}
191impl Oled128x64V2Bricklet {
192 pub const DEVICE_IDENTIFIER: u16 = 2112;
193 pub const DEVICE_DISPLAY_NAME: &'static str = "OLED 128x64 Bricklet 2.0";
194 pub fn new<T: GetRequestSender>(uid: &str, req_sender: T) -> Oled128x64V2Bricklet {
196 let mut result = Oled128x64V2Bricklet { device: Device::new([2, 0, 0], uid, req_sender, 2) };
197 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::WritePixelsLowLevel) as usize] = ResponseExpectedFlag::True;
198 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::ReadPixelsLowLevel) as usize] =
199 ResponseExpectedFlag::AlwaysTrue;
200 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::ClearDisplay) as usize] = ResponseExpectedFlag::False;
201 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::SetDisplayConfiguration) as usize] =
202 ResponseExpectedFlag::False;
203 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::GetDisplayConfiguration) as usize] =
204 ResponseExpectedFlag::AlwaysTrue;
205 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::WriteLine) as usize] = ResponseExpectedFlag::False;
206 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::DrawBufferedFrame) as usize] = ResponseExpectedFlag::False;
207 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::GetSpitfpErrorCount) as usize] =
208 ResponseExpectedFlag::AlwaysTrue;
209 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::SetBootloaderMode) as usize] =
210 ResponseExpectedFlag::AlwaysTrue;
211 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::GetBootloaderMode) as usize] =
212 ResponseExpectedFlag::AlwaysTrue;
213 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::SetWriteFirmwarePointer) as usize] =
214 ResponseExpectedFlag::False;
215 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::WriteFirmware) as usize] = ResponseExpectedFlag::AlwaysTrue;
216 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::SetStatusLedConfig) as usize] = ResponseExpectedFlag::False;
217 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::GetStatusLedConfig) as usize] =
218 ResponseExpectedFlag::AlwaysTrue;
219 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::GetChipTemperature) as usize] =
220 ResponseExpectedFlag::AlwaysTrue;
221 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
222 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
223 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
224 result.device.response_expected[u8::from(Oled128x64V2BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
225 result
226 }
227
228 pub fn get_response_expected(&mut self, fun: Oled128x64V2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
243 self.device.get_response_expected(u8::from(fun))
244 }
245
246 pub fn set_response_expected(
255 &mut self,
256 fun: Oled128x64V2BrickletFunction,
257 response_expected: bool,
258 ) -> Result<(), SetResponseExpectedError> {
259 self.device.set_response_expected(u8::from(fun), response_expected)
260 }
261
262 pub fn set_response_expected_all(&mut self, response_expected: bool) { self.device.set_response_expected_all(response_expected) }
264
265 pub fn get_api_version(&self) -> [u8; 3] { self.device.api_version }
268
269 pub fn write_pixels_low_level(
289 &self,
290 x_start: u8,
291 y_start: u8,
292 x_end: u8,
293 y_end: u8,
294 pixels_length: u16,
295 pixels_chunk_offset: u16,
296 pixels_chunk_data: [bool; 448],
297 ) -> ConvertingReceiver<WritePixelsLowLevel> {
298 let mut payload = vec![0; 64];
299 payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(x_start));
300 payload[1..2].copy_from_slice(&<u8>::to_le_byte_vec(y_start));
301 payload[2..3].copy_from_slice(&<u8>::to_le_byte_vec(x_end));
302 payload[3..4].copy_from_slice(&<u8>::to_le_byte_vec(y_end));
303 payload[4..6].copy_from_slice(&<u16>::to_le_byte_vec(pixels_length));
304 payload[6..8].copy_from_slice(&<u16>::to_le_byte_vec(pixels_chunk_offset));
305 payload[8..64].copy_from_slice(&<[bool; 448]>::to_le_byte_vec(pixels_chunk_data));
306
307 self.device.set(u8::from(Oled128x64V2BrickletFunction::WritePixelsLowLevel), payload)
308 }
309
310 pub fn write_pixels(&self, x_start: u8, y_start: u8, x_end: u8, y_end: u8, pixels: &[bool]) -> Result<(), BrickletRecvTimeoutError> {
327 let _ll_result = self.device.set_high_level(0, pixels, 65535, 448, &mut |length: usize, chunk_offset: usize, chunk: &[bool]| {
328 let chunk_length = chunk.len() as u16;
329 let mut chunk_array = [<bool>::default(); 448];
330 chunk_array[0..chunk_length as usize].copy_from_slice(&chunk);
331
332 let result =
333 self.write_pixels_low_level(x_start, y_start, x_end, y_end, length as u16, chunk_offset as u16, chunk_array).recv();
334 if let Err(BrickletRecvTimeoutError::SuccessButResponseExpectedIsDisabled) = result {
335 Ok(Default::default())
336 } else {
337 result
338 }
339 })?;
340 Ok(())
341 }
342
343 pub fn read_pixels_low_level(&self, x_start: u8, y_start: u8, x_end: u8, y_end: u8) -> ConvertingReceiver<ReadPixelsLowLevel> {
357 let mut payload = vec![0; 4];
358 payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(x_start));
359 payload[1..2].copy_from_slice(&<u8>::to_le_byte_vec(y_start));
360 payload[2..3].copy_from_slice(&<u8>::to_le_byte_vec(x_end));
361 payload[3..4].copy_from_slice(&<u8>::to_le_byte_vec(y_end));
362
363 self.device.get(u8::from(Oled128x64V2BrickletFunction::ReadPixelsLowLevel), payload)
364 }
365
366 pub fn read_pixels(&self, x_start: u8, y_start: u8, x_end: u8, y_end: u8) -> Result<Vec<bool>, BrickletRecvTimeoutError> {
380 let ll_result = self.device.get_high_level(1, &mut || self.read_pixels_low_level(x_start, y_start, x_end, y_end).recv())?;
381 Ok(ll_result.0)
382 }
383
384 pub fn clear_display(&self) -> ConvertingReceiver<()> {
396 let payload = vec![0; 0];
397
398 self.device.set(u8::from(Oled128x64V2BrickletFunction::ClearDisplay), payload)
399 }
400
401 pub fn set_display_configuration(&self, contrast: u8, invert: bool, automatic_draw: bool) -> ConvertingReceiver<()> {
411 let mut payload = vec![0; 3];
412 payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(contrast));
413 payload[1..2].copy_from_slice(&<bool>::to_le_byte_vec(invert));
414 payload[2..3].copy_from_slice(&<bool>::to_le_byte_vec(automatic_draw));
415
416 self.device.set(u8::from(Oled128x64V2BrickletFunction::SetDisplayConfiguration), payload)
417 }
418
419 pub fn get_display_configuration(&self) -> ConvertingReceiver<DisplayConfiguration> {
421 let payload = vec![0; 0];
422
423 self.device.get(u8::from(Oled128x64V2BrickletFunction::GetDisplayConfiguration), payload)
424 }
425
426 pub fn write_line(&self, line: u8, position: u8, text: String) -> ConvertingReceiver<()> {
449 let mut payload = vec![0; 24];
450 payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(line));
451 payload[1..2].copy_from_slice(&<u8>::to_le_byte_vec(position));
452 match <String>::try_to_le_byte_vec(text, 22) {
453 Err(e) => {
454 let (tx, rx) = std::sync::mpsc::channel::<Result<Vec<u8>, BrickletError>>();
455 let _ = tx.send(Err(e));
456 return ConvertingReceiver::new(rx, std::time::Duration::new(1, 0));
457 }
458 Ok(bytes) => payload[2..24].copy_from_slice(&bytes),
459 }
460
461 self.device.set(u8::from(Oled128x64V2BrickletFunction::WriteLine), payload)
462 }
463
464 pub fn draw_buffered_frame(&self, force_complete_redraw: bool) -> ConvertingReceiver<()> {
474 let mut payload = vec![0; 1];
475 payload[0..1].copy_from_slice(&<bool>::to_le_byte_vec(force_complete_redraw));
476
477 self.device.set(u8::from(Oled128x64V2BrickletFunction::DrawBufferedFrame), payload)
478 }
479
480 pub fn get_spitfp_error_count(&self) -> ConvertingReceiver<SpitfpErrorCount> {
492 let payload = vec![0; 0];
493
494 self.device.get(u8::from(Oled128x64V2BrickletFunction::GetSpitfpErrorCount), payload)
495 }
496
497 pub fn set_bootloader_mode(&self, mode: u8) -> ConvertingReceiver<u8> {
520 let mut payload = vec![0; 1];
521 payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(mode));
522
523 self.device.get(u8::from(Oled128x64V2BrickletFunction::SetBootloaderMode), payload)
524 }
525
526 pub fn get_bootloader_mode(&self) -> ConvertingReceiver<u8> {
535 let payload = vec![0; 0];
536
537 self.device.get(u8::from(Oled128x64V2BrickletFunction::GetBootloaderMode), payload)
538 }
539
540 pub fn set_write_firmware_pointer(&self, pointer: u32) -> ConvertingReceiver<()> {
547 let mut payload = vec![0; 4];
548 payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(pointer));
549
550 self.device.set(u8::from(Oled128x64V2BrickletFunction::SetWriteFirmwarePointer), payload)
551 }
552
553 pub fn write_firmware(&self, data: [u8; 64]) -> ConvertingReceiver<u8> {
562 let mut payload = vec![0; 64];
563 payload[0..64].copy_from_slice(&<[u8; 64]>::to_le_byte_vec(data));
564
565 self.device.get(u8::from(Oled128x64V2BrickletFunction::WriteFirmware), payload)
566 }
567
568 pub fn set_status_led_config(&self, config: u8) -> ConvertingReceiver<()> {
582 let mut payload = vec![0; 1];
583 payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(config));
584
585 self.device.set(u8::from(Oled128x64V2BrickletFunction::SetStatusLedConfig), payload)
586 }
587
588 pub fn get_status_led_config(&self) -> ConvertingReceiver<u8> {
596 let payload = vec![0; 0];
597
598 self.device.get(u8::from(Oled128x64V2BrickletFunction::GetStatusLedConfig), payload)
599 }
600
601 pub fn get_chip_temperature(&self) -> ConvertingReceiver<i16> {
608 let payload = vec![0; 0];
609
610 self.device.get(u8::from(Oled128x64V2BrickletFunction::GetChipTemperature), payload)
611 }
612
613 pub fn reset(&self) -> ConvertingReceiver<()> {
620 let payload = vec![0; 0];
621
622 self.device.set(u8::from(Oled128x64V2BrickletFunction::Reset), payload)
623 }
624
625 pub fn write_uid(&self, uid: u32) -> ConvertingReceiver<()> {
631 let mut payload = vec![0; 4];
632 payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(uid));
633
634 self.device.set(u8::from(Oled128x64V2BrickletFunction::WriteUid), payload)
635 }
636
637 pub fn read_uid(&self) -> ConvertingReceiver<u32> {
640 let payload = vec![0; 0];
641
642 self.device.get(u8::from(Oled128x64V2BrickletFunction::ReadUid), payload)
643 }
644
645 pub fn get_identity(&self) -> ConvertingReceiver<Identity> {
656 let payload = vec![0; 0];
657
658 self.device.get(u8::from(Oled128x64V2BrickletFunction::GetIdentity), payload)
659 }
660}