1use crate::device::PoKeysDevice;
13use crate::error::{PoKeysError, Result};
14use serde::{Deserialize, Serialize};
15
16pub const MAX_ENCODERS: usize = 25;
18
19pub const MAX_FAST_ENCODERS: usize = 3;
21
22pub const ULTRA_FAST_ENCODER_INDEX: u8 = 25;
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct EncoderOptions {
28 pub enabled: bool,
30 pub sampling_4x: bool,
32 pub sampling_2x: bool,
34 pub direct_key_mapping_a: bool,
36 pub macro_mapping_a: bool,
38 pub direct_key_mapping_b: bool,
40 pub macro_mapping_b: bool,
42}
43
44impl Default for EncoderOptions {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl EncoderOptions {
51 pub fn new() -> Self {
53 Self {
54 enabled: false,
55 sampling_4x: false,
56 sampling_2x: false,
57 direct_key_mapping_a: false,
58 macro_mapping_a: false,
59 direct_key_mapping_b: false,
60 macro_mapping_b: false,
61 }
62 }
63
64 pub fn with_4x_sampling() -> Self {
66 Self {
67 enabled: true,
68 sampling_4x: true,
69 sampling_2x: false,
70 direct_key_mapping_a: false,
71 macro_mapping_a: false,
72 direct_key_mapping_b: false,
73 macro_mapping_b: false,
74 }
75 }
76
77 pub fn with_2x_sampling() -> Self {
79 Self {
80 enabled: true,
81 sampling_4x: false,
82 sampling_2x: true,
83 direct_key_mapping_a: false,
84 macro_mapping_a: false,
85 direct_key_mapping_b: false,
86 macro_mapping_b: false,
87 }
88 }
89
90 pub fn to_byte(&self) -> u8 {
93 let mut options = 0u8;
94 if self.enabled {
95 options |= 1 << 0;
96 }
97 if self.sampling_4x {
98 options |= 1 << 1;
99 }
100 if self.sampling_2x {
101 options |= 1 << 2;
102 }
103 if self.direct_key_mapping_a {
105 options |= 1 << 4;
106 }
107 if self.macro_mapping_a {
108 options |= 1 << 5;
109 }
110 if self.direct_key_mapping_b {
111 options |= 1 << 6;
112 }
113 if self.macro_mapping_b {
114 options |= 1 << 7;
115 }
116 options
117 }
118
119 pub fn from_byte(byte: u8) -> Self {
121 Self {
122 enabled: (byte & (1 << 0)) != 0,
123 sampling_4x: (byte & (1 << 1)) != 0,
124 sampling_2x: (byte & (1 << 2)) != 0,
125 direct_key_mapping_a: (byte & (1 << 4)) != 0,
126 macro_mapping_a: (byte & (1 << 5)) != 0,
127 direct_key_mapping_b: (byte & (1 << 6)) != 0,
128 macro_mapping_b: (byte & (1 << 7)) != 0,
129 }
130 }
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct EncoderData {
136 pub encoder_value: i32,
138 pub encoder_options: u8,
140 pub channel_a_pin: u8,
142 pub channel_b_pin: u8,
144 pub dir_a_key_code: u8,
146 pub dir_a_key_modifier: u8,
148 pub dir_b_key_code: u8,
150 pub dir_b_key_modifier: u8,
152}
153
154impl EncoderData {
155 pub fn new() -> Self {
157 Self {
158 encoder_value: 0,
159 encoder_options: 0,
160 channel_a_pin: 0,
161 channel_b_pin: 0,
162 dir_a_key_code: 0,
163 dir_a_key_modifier: 0,
164 dir_b_key_code: 0,
165 dir_b_key_modifier: 0,
166 }
167 }
168
169 pub fn get_options(&self) -> EncoderOptions {
171 EncoderOptions::from_byte(self.encoder_options)
172 }
173
174 pub fn set_options(&mut self, options: EncoderOptions) {
176 self.encoder_options = options.to_byte();
177 }
178
179 pub fn is_enabled(&self) -> bool {
181 (self.encoder_options & 1) != 0
182 }
183
184 pub fn is_4x_sampling(&self) -> bool {
186 (self.encoder_options & (1 << 1)) != 0
187 }
188
189 pub fn is_2x_sampling(&self) -> bool {
191 (self.encoder_options & (1 << 2)) != 0
192 }
193
194 pub fn sampling_mode_str(&self) -> &'static str {
196 if self.is_4x_sampling() {
197 "4x (both edges)"
198 } else if self.is_2x_sampling() {
199 "2x (A edges only)"
200 } else {
201 "1x (disabled)"
202 }
203 }
204}
205
206impl Default for EncoderData {
207 fn default() -> Self {
208 Self::new()
209 }
210}
211
212impl PoKeysDevice {
213 pub fn configure_encoder(
216 &mut self,
217 encoder_id: u8,
218 channel_a_pin: u8,
219 channel_b_pin: u8,
220 options: EncoderOptions,
221 ) -> Result<()> {
222 if encoder_id as usize >= self.encoders.len() {
223 return Err(PoKeysError::Parameter(format!(
224 "Invalid encoder ID: {}",
225 encoder_id
226 )));
227 }
228
229 let protocol_pin_a = if channel_a_pin > 0 {
232 channel_a_pin - 1
233 } else {
234 0
235 };
236 let protocol_pin_b = if channel_b_pin > 0 {
237 channel_b_pin - 1
238 } else {
239 0
240 };
241
242 let encoder = &mut self.encoders[encoder_id as usize];
243 encoder.channel_a_pin = protocol_pin_a; encoder.channel_b_pin = protocol_pin_b; encoder.set_options(options);
246
247 log::info!(
248 "Configuring encoder {} with pins A={}, B={} (1-based: A={}, B={}), options={:08b} using protocol 0x11",
249 encoder_id,
250 protocol_pin_a,
251 protocol_pin_b,
252 channel_a_pin,
253 channel_b_pin,
254 options.to_byte()
255 );
256
257 let response = self.send_request(
260 0x11, encoder_id, options.to_byte(), protocol_pin_a, protocol_pin_b, )?;
266
267 log::info!("Encoder configuration response: {:?}", &response[0..8]);
268
269 if response.len() > 2 {
271 match response[2] {
272 0 => {
274 log::info!("Encoder {} configuration successful", encoder_id);
275 }
276 1 => {
277 return Err(PoKeysError::Protocol(format!(
278 "Encoder {} configuration failed: encoder ID out of range or configuration locked",
279 encoder_id
280 )));
281 }
282 other => {
283 return Err(PoKeysError::Protocol(format!(
284 "Encoder {} configuration failed with status: {} (0x{:02X})",
285 encoder_id, other, other
286 )));
287 }
288 }
289 }
290
291 Ok(())
292 }
293
294 pub fn read_encoder_settings(&mut self, encoder_id: u8) -> Result<EncoderData> {
296 if encoder_id >= MAX_ENCODERS as u8 {
297 return Err(PoKeysError::Parameter(format!(
298 "Encoder ID {} exceeds maximum {}",
299 encoder_id, MAX_ENCODERS
300 )));
301 }
302
303 log::info!(
304 "Reading encoder {} settings using protocol 0x16",
305 encoder_id
306 );
307
308 let response = self.send_request(
311 0x16, encoder_id, 0, 0, 0, )?;
317
318 log::info!("Read encoder settings response: {:?}", &response[0..8]);
319
320 if response.len() >= 6 {
323 let returned_encoder_id = response[2]; let options_byte = response[3]; let channel_a_pin = response[4]; let channel_b_pin = response[5]; if returned_encoder_id != encoder_id {
329 log::warn!(
330 "Response encoder ID {} doesn't match requested {}",
331 returned_encoder_id,
332 encoder_id
333 );
334 }
335
336 let display_pin_a = channel_a_pin + 1;
338 let display_pin_b = channel_b_pin + 1;
339
340 let settings = EncoderData {
341 channel_a_pin: display_pin_a, channel_b_pin: display_pin_b, encoder_options: options_byte,
344 ..Default::default()
345 };
346
347 log::info!(
348 "Encoder {} settings: A={}, B={} (protocol: A={}, B={}), options={:08b}",
349 encoder_id,
350 display_pin_a,
351 display_pin_b,
352 channel_a_pin,
353 channel_b_pin,
354 options_byte
355 );
356
357 Ok(settings)
358 } else {
359 Err(PoKeysError::Protocol(
360 "Invalid encoder settings response length".to_string(),
361 ))
362 }
363 }
364
365 pub fn enable_encoder(&mut self, encoder_id: u8, enable: bool) -> Result<()> {
367 if encoder_id as usize >= self.encoders.len() {
368 return Err(PoKeysError::Parameter(format!(
369 "Invalid encoder ID: {}",
370 encoder_id
371 )));
372 }
373
374 let (channel_a_pin, channel_b_pin) = {
376 let encoder = &self.encoders[encoder_id as usize];
377 (encoder.channel_a_pin, encoder.channel_b_pin)
378 };
379
380 let mut options = {
382 let encoder = &self.encoders[encoder_id as usize];
383 encoder.get_options()
384 };
385 options.enabled = enable;
386
387 self.configure_encoder(encoder_id, channel_a_pin, channel_b_pin, options)
388 }
389
390 pub fn set_encoder_sampling(
392 &mut self,
393 encoder_id: u8,
394 sampling_4x: bool,
395 sampling_2x: bool,
396 ) -> Result<()> {
397 if encoder_id as usize >= self.encoders.len() {
398 return Err(PoKeysError::Parameter(format!(
399 "Invalid encoder ID: {}",
400 encoder_id
401 )));
402 }
403
404 if sampling_4x && sampling_2x {
406 return Err(PoKeysError::Parameter(
407 "Cannot enable both 4x and 2x sampling simultaneously".to_string(),
408 ));
409 }
410
411 let (channel_a_pin, channel_b_pin) = {
413 let encoder = &self.encoders[encoder_id as usize];
414 (encoder.channel_a_pin, encoder.channel_b_pin)
415 };
416
417 let mut options = {
419 let encoder = &self.encoders[encoder_id as usize];
420 encoder.get_options()
421 };
422 options.sampling_4x = sampling_4x;
423 options.sampling_2x = sampling_2x;
424
425 self.configure_encoder(encoder_id, channel_a_pin, channel_b_pin, options)
426 }
427
428 pub fn configure_encoder_key_mapping_a(
431 &mut self,
432 encoder_id: u8,
433 key_code: u8,
434 key_modifier: u8,
435 ) -> Result<()> {
436 if encoder_id as usize >= self.encoders.len() {
437 return Err(PoKeysError::Parameter(format!(
438 "Invalid encoder ID: {}",
439 encoder_id
440 )));
441 }
442
443 let encoder = &mut self.encoders[encoder_id as usize];
444 encoder.dir_a_key_code = key_code;
445 encoder.dir_a_key_modifier = key_modifier;
446
447 let response = self.send_request(
449 0x12, encoder_id, 0, key_code, key_modifier, )?;
455
456 if response.len() > 3 && response[3] != 0 {
458 return Err(PoKeysError::Protocol(format!(
459 "Encoder key mapping A failed for encoder {}: status {}",
460 encoder_id, response[3]
461 )));
462 }
463
464 Ok(())
465 }
466
467 pub fn configure_encoder_key_mapping_b(
470 &mut self,
471 encoder_id: u8,
472 key_code: u8,
473 key_modifier: u8,
474 ) -> Result<()> {
475 if encoder_id as usize >= self.encoders.len() {
476 return Err(PoKeysError::Parameter(format!(
477 "Invalid encoder ID: {}",
478 encoder_id
479 )));
480 }
481
482 let encoder = &mut self.encoders[encoder_id as usize];
483 encoder.dir_b_key_code = key_code;
484 encoder.dir_b_key_modifier = key_modifier;
485
486 let response = self.send_request(
488 0x13, encoder_id, 0, key_code, key_modifier, )?;
494
495 if response.len() > 3 && response[3] != 0 {
497 return Err(PoKeysError::Protocol(format!(
498 "Encoder key mapping B failed for encoder {}: status {}",
499 encoder_id, response[3]
500 )));
501 }
502
503 Ok(())
504 }
505
506 pub fn read_encoder_key_mapping_a(&mut self, encoder_id: u8) -> Result<(u8, u8)> {
509 if encoder_id as usize >= self.encoders.len() {
510 return Err(PoKeysError::Parameter(format!(
511 "Invalid encoder ID: {}",
512 encoder_id
513 )));
514 }
515
516 let response = self.send_request(
517 0x17, encoder_id, 0, 0, 0, )?;
523
524 if response.len() < 8 {
525 return Err(PoKeysError::Protocol("Invalid response length".to_string()));
526 }
527
528 let key_code = response[5];
530 let key_modifier = response[6];
531
532 self.encoders[encoder_id as usize].dir_a_key_code = key_code;
534 self.encoders[encoder_id as usize].dir_a_key_modifier = key_modifier;
535
536 Ok((key_code, key_modifier))
537 }
538
539 pub fn read_encoder_key_mapping_b(&mut self, encoder_id: u8) -> Result<(u8, u8)> {
542 if encoder_id as usize >= self.encoders.len() {
543 return Err(PoKeysError::Parameter(format!(
544 "Invalid encoder ID: {}",
545 encoder_id
546 )));
547 }
548
549 let response = self.send_request(
550 0x18, encoder_id, 0, 0, 0, )?;
556
557 if response.len() < 8 {
558 return Err(PoKeysError::Protocol("Invalid response length".to_string()));
559 }
560
561 let key_code = response[5];
563 let key_modifier = response[6];
564
565 self.encoders[encoder_id as usize].dir_b_key_code = key_code;
567 self.encoders[encoder_id as usize].dir_b_key_modifier = key_modifier;
568
569 Ok((key_code, key_modifier))
570 }
571
572 pub fn read_encoder_raw_value(&mut self, encoder_id: u8) -> Result<i32> {
575 if encoder_id as usize >= self.encoders.len() {
576 return Err(PoKeysError::Parameter(format!(
577 "Invalid encoder ID: {}",
578 encoder_id
579 )));
580 }
581
582 let response = self.send_request(
583 0x19, encoder_id, 0, 0, 0, )?;
589
590 if response.len() < 8 {
591 return Err(PoKeysError::Protocol("Invalid response length".to_string()));
592 }
593
594 let raw_value = response[4] as i8 as i32; self.encoders[encoder_id as usize].encoder_value = raw_value;
600
601 Ok(raw_value)
602 }
603
604 pub fn reset_encoder_raw_value(&mut self, encoder_id: u8) -> Result<()> {
607 if encoder_id as usize >= self.encoders.len() {
608 return Err(PoKeysError::Parameter(format!(
609 "Invalid encoder ID: {}",
610 encoder_id
611 )));
612 }
613
614 let response = self.send_request(
615 0x1A, encoder_id, 0, 0, 0, )?;
621
622 if response.len() < 8 {
624 return Err(PoKeysError::Protocol("Invalid response length".to_string()));
625 }
626
627 self.encoders[encoder_id as usize].encoder_value = 0;
629
630 Ok(())
631 }
632
633 pub fn get_encoder_value(&mut self, encoder_id: u8) -> Result<i32> {
635 self.read_encoder_raw_value(encoder_id)
636 }
637
638 pub fn reset_encoder(&mut self, encoder_id: u8) -> Result<()> {
640 self.reset_encoder_raw_value(encoder_id)
641 }
642
643 pub fn read_encoder_long_values(&mut self, group: u8) -> Result<Vec<i32>> {
647 if group > 1 {
648 return Err(PoKeysError::Parameter(
649 "Group must be 0 (encoders 1-13) or 1 (encoders 14-26)".to_string(),
650 ));
651 }
652
653 let response = self.send_request(
654 0xCD, group, 0, 0, 0, )?;
660
661 if response.len() < 64 {
662 return Err(PoKeysError::Protocol(
663 "Invalid response length for bulk encoder read".to_string(),
664 ));
665 }
666
667 let mut values = Vec::new();
668
669 for i in 0..13 {
672 let byte_offset = 8 + (i * 4); if byte_offset + 3 < response.len() {
674 let value = i32::from_le_bytes([
675 response[byte_offset],
676 response[byte_offset + 1],
677 response[byte_offset + 2],
678 response[byte_offset + 3],
679 ]);
680 values.push(value);
681
682 let encoder_index = if group == 0 { i } else { 13 + i };
684 if encoder_index < self.encoders.len() {
685 self.encoders[encoder_index].encoder_value = value;
686 }
687 }
688 }
689
690 if group == 1 && response.len() >= 60 {
692 let ultra_fast_value = i32::from_le_bytes([
693 response[56], response[57], response[58], response[59], ]);
698 if self.encoders.len() > 25 {
700 self.encoders[25].encoder_value = ultra_fast_value;
701 }
702 }
703
704 log::info!("Bulk read group {} returned {} values", group, values.len());
705 Ok(values)
706 }
707
708 pub fn set_encoder_long_values(&mut self, group: u8, values: &[i32]) -> Result<()> {
712 if group > 1 {
713 return Err(PoKeysError::Parameter(
714 "Group must be 0 (encoders 1-13) or 1 (encoders 14-26)".to_string(),
715 ));
716 }
717
718 let expected_count = if group == 0 { 13 } else { 12 }; if values.len() < expected_count {
720 return Err(PoKeysError::Parameter(format!(
721 "Need {} values for group {}",
722 expected_count, group
723 )));
724 }
725
726 let mut request = vec![0u8; 64];
728 request[2] = 0xCD; request[3] = group + 10; request[7] = self.get_next_request_id(); for (i, &value) in values.iter().enumerate() {
734 let byte_offset = 9 + (i * 4);
735 if byte_offset + 3 < request.len() {
736 let bytes = value.to_le_bytes();
737 request[byte_offset] = bytes[0];
738 request[byte_offset + 1] = bytes[1];
739 request[byte_offset + 2] = bytes[2];
740 request[byte_offset + 3] = bytes[3];
741 }
742 }
743
744 let _response = self.send_raw_request(&request)?;
745
746 let start_encoder = if group == 0 { 1 } else { 14 };
748 for (i, &value) in values.iter().enumerate() {
749 let encoder_index = start_encoder + i;
750 if encoder_index < self.encoders.len() {
751 self.encoders[encoder_index].encoder_value = value;
752 }
753 }
754
755 Ok(())
756 }
757
758 pub fn read_all_encoder_values(&mut self) -> Result<Vec<i32>> {
760 let mut all_values = Vec::new();
761
762 let group1_values = self.read_encoder_long_values(0)?;
764 all_values.extend(group1_values);
765
766 let group2_values = self.read_encoder_long_values(1)?;
768 all_values.extend(group2_values);
769
770 Ok(all_values)
771 }
772
773 pub fn configure_encoder_options_bulk(&mut self, options: &[u8]) -> Result<Vec<u8>> {
776 if options.len() != 25 {
777 return Err(PoKeysError::Parameter(
778 "Need exactly 25 encoder options".to_string(),
779 ));
780 }
781
782 let mut request = vec![0u8; 64];
783 request[2] = 0xC4; request[3] = 1; request[7] = self.get_next_request_id(); for (i, &option) in options.iter().enumerate() {
789 request[9 + i] = option;
790 }
791
792 let response = self.send_raw_request(&request)?;
793
794 let mut returned_options = Vec::new();
796 if response.len() >= 34 {
797 for i in 0..25 {
798 returned_options.push(response[9 + i]);
799 if i < self.encoders.len() {
801 self.encoders[i].encoder_options = response[9 + i];
802 }
803 }
804 }
805
806 Ok(returned_options)
807 }
808
809 pub fn read_encoder_options_bulk(&mut self) -> Result<Vec<u8>> {
812 let response = self.send_request(
813 0xC4, 0, 0, 0, 0, )?;
819
820 let mut options = Vec::new();
821 if response.len() >= 34 {
822 for i in 0..25 {
823 options.push(response[9 + i]);
824 if i < self.encoders.len() {
826 self.encoders[i].encoder_options = response[9 + i];
827 }
828 }
829 }
830
831 Ok(options)
832 }
833
834 pub fn configure_fast_encoders(&mut self, options: u8, enable_index: bool) -> Result<()> {
839 self.fast_encoders_options = options;
840
841 let response = self.send_request(
842 0xCE, options, if enable_index { 1 } else { 0 }, 0, 0, )?;
848
849 if response.len() > 3 {
851 let status = response[3];
852 if status != 0 {
853 return Err(PoKeysError::Protocol(format!(
854 "Fast encoder configuration failed: status {}",
855 status
856 )));
857 }
858 }
859
860 Ok(())
861 }
862
863 pub fn read_fast_encoder_values(&mut self) -> Result<[i32; 3]> {
865 let values = self.read_encoder_long_values(0)?;
867
868 let mut fast_values = [0i32; 3];
869 let copy_len = 3.min(values.len());
870 fast_values[..copy_len].copy_from_slice(&values[..copy_len]);
871
872 Ok(fast_values)
873 }
874
875 pub fn configure_ultra_fast_encoder(
879 &mut self,
880 enable: bool,
881 enable_4x_sampling: bool,
882 signal_mode_direction_clock: bool,
883 invert_direction: bool,
884 reset_on_index: bool,
885 filter_delay: u32,
886 ) -> Result<()> {
887 let mut options = 0u8;
889 if enable_4x_sampling {
890 options |= 1 << 1; }
892 if signal_mode_direction_clock {
893 options |= 1 << 2; }
895 if invert_direction {
896 options |= 1 << 3; }
898
899 self.ultra_fast_encoder_configuration = if enable { 1 } else { 0 };
900 self.ultra_fast_encoder_options = options;
901 self.ultra_fast_encoder_filter = filter_delay;
902
903 let mut request = vec![0u8; 64];
905 request[2] = 0x1C; request[3] = if enable { 1 } else { 0 }; request[4] = options; request[5] = if reset_on_index { 1 } else { 0 }; request[6] = 0; request[7] = self.get_next_request_id(); let filter_bytes = filter_delay.to_le_bytes();
914 request[9] = filter_bytes[0];
915 request[10] = filter_bytes[1];
916 request[11] = filter_bytes[2];
917 request[12] = filter_bytes[3];
918
919 let response = self.send_raw_request(&request)?;
920
921 if response.len() > 3 {
923 let status = response[3];
924 if status != 0 {
925 return Err(PoKeysError::Protocol(format!(
926 "Ultra-fast encoder configuration failed: status {}",
927 status
928 )));
929 }
930 }
931
932 Ok(())
933 }
934
935 pub fn read_ultra_fast_encoder_config(&mut self) -> Result<(bool, u8, u32)> {
938 let mut request = vec![0u8; 64];
939 request[2] = 0x1C; request[3] = 0xFF; request[7] = self.get_next_request_id(); let response = self.send_raw_request(&request)?;
944
945 if response.len() < 13 {
946 return Err(PoKeysError::Protocol("Invalid response length".to_string()));
947 }
948
949 let enabled = response[3] != 0;
950 let options = response[4];
951 let filter_delay =
952 u32::from_le_bytes([response[9], response[10], response[11], response[12]]);
953
954 Ok((enabled, options, filter_delay))
955 }
956
957 pub fn read_ultra_fast_encoder_value(&mut self) -> Result<i32> {
959 let values = self.read_encoder_long_values(1)?;
961
962 if let Some(&value) = values.last() {
964 Ok(value)
965 } else {
966 Err(PoKeysError::Protocol(
967 "No ultra-fast encoder value in response".to_string(),
968 ))
969 }
970 }
971
972 pub fn set_ultra_fast_encoder_value(&mut self, value: i32) -> Result<()> {
974 let mut values = self.read_encoder_long_values(1)?;
977
978 if let Some(last) = values.last_mut() {
980 *last = value;
981 } else {
982 return Err(PoKeysError::Protocol(
983 "Cannot set ultra-fast encoder value".to_string(),
984 ));
985 }
986
987 self.set_encoder_long_values(1, &values)
988 }
989 #[allow(clippy::too_many_arguments)]
991 pub fn configure_encoder_with_keys(
992 &mut self,
993 encoder_id: u8,
994 channel_a_pin: u8,
995 channel_b_pin: u8,
996 sampling_4x: bool,
997 sampling_2x: bool,
998 dir_a_key_code: u8,
999 dir_a_key_modifier: u8,
1000 dir_b_key_code: u8,
1001 dir_b_key_modifier: u8,
1002 ) -> Result<()> {
1003 let mut options = EncoderOptions::new();
1005 options.enabled = true;
1006 options.sampling_4x = sampling_4x;
1007 options.sampling_2x = sampling_2x;
1008 options.direct_key_mapping_a = true;
1009 options.direct_key_mapping_b = true;
1010
1011 self.configure_encoder(encoder_id, channel_a_pin, channel_b_pin, options)?;
1012
1013 self.configure_encoder_key_mapping_a(encoder_id, dir_a_key_code, dir_a_key_modifier)?;
1015 self.configure_encoder_key_mapping_b(encoder_id, dir_b_key_code, dir_b_key_modifier)?;
1016
1017 Ok(())
1018 }
1019
1020 pub fn get_encoder_sampling_mode(&self, encoder_id: u8) -> Result<String> {
1022 if encoder_id as usize >= self.encoders.len() {
1023 return Err(PoKeysError::Parameter(format!(
1024 "Invalid encoder ID: {}",
1025 encoder_id
1026 )));
1027 }
1028
1029 let encoder = &self.encoders[encoder_id as usize];
1030 Ok(encoder.sampling_mode_str().to_string())
1031 }
1032
1033 pub fn is_encoder_4x_sampling(&self, encoder_id: u8) -> Result<bool> {
1035 if encoder_id as usize >= self.encoders.len() {
1036 return Err(PoKeysError::Parameter(format!(
1037 "Invalid encoder ID: {}",
1038 encoder_id
1039 )));
1040 }
1041
1042 Ok(self.encoders[encoder_id as usize].is_4x_sampling())
1043 }
1044
1045 pub fn is_encoder_2x_sampling(&self, encoder_id: u8) -> Result<bool> {
1047 if encoder_id as usize >= self.encoders.len() {
1048 return Err(PoKeysError::Parameter(format!(
1049 "Invalid encoder ID: {}",
1050 encoder_id
1051 )));
1052 }
1053
1054 Ok(self.encoders[encoder_id as usize].is_2x_sampling())
1055 }
1056
1057 pub fn get_enabled_encoders(&self) -> Vec<u8> {
1059 self.encoders
1060 .iter()
1061 .enumerate()
1062 .filter_map(|(i, encoder)| {
1063 if encoder.is_enabled() {
1064 Some(i as u8)
1065 } else {
1066 None
1067 }
1068 })
1069 .collect()
1070 }
1071
1072 fn get_next_request_id(&mut self) -> u8 {
1074 static mut REQUEST_ID: u8 = 0;
1077 unsafe {
1078 REQUEST_ID = REQUEST_ID.wrapping_add(1);
1079 REQUEST_ID
1080 }
1081 }
1082
1083 fn send_raw_request(&mut self, request: &[u8]) -> Result<Vec<u8>> {
1085 if request.len() >= 8 {
1088 let response_array =
1089 self.send_request(request[2], request[3], request[4], request[5], request[6])?;
1090 Ok(response_array.to_vec())
1091 } else {
1092 Err(PoKeysError::Protocol("Invalid request format".to_string()))
1093 }
1094 }
1095}
1096
1097#[cfg(test)]
1098mod tests {
1099 use super::*;
1100
1101 #[test]
1102 fn test_encoder_options_4x_sampling() {
1103 let options = EncoderOptions::with_4x_sampling();
1104 assert!(options.enabled);
1105 assert!(options.sampling_4x);
1106 assert!(!options.sampling_2x);
1107
1108 let byte = options.to_byte();
1109 assert_eq!(byte & 0b00000011, 0b00000011); let options_from_byte = EncoderOptions::from_byte(byte);
1112 assert!(options_from_byte.enabled);
1113 assert!(options_from_byte.sampling_4x);
1114 assert!(!options_from_byte.sampling_2x);
1115 }
1116
1117 #[test]
1118 fn test_encoder_options_2x_sampling() {
1119 let options = EncoderOptions::with_2x_sampling();
1120 assert!(options.enabled);
1121 assert!(!options.sampling_4x);
1122 assert!(options.sampling_2x);
1123
1124 let byte = options.to_byte();
1125 assert_eq!(byte & 0b00000111, 0b00000101); let options_from_byte = EncoderOptions::from_byte(byte);
1128 assert!(options_from_byte.enabled);
1129 assert!(!options_from_byte.sampling_4x);
1130 assert!(options_from_byte.sampling_2x);
1131 }
1132
1133 #[test]
1134 fn test_encoder_options_key_mapping() {
1135 let mut options = EncoderOptions::new();
1136 options.enabled = true;
1137 options.direct_key_mapping_a = true;
1138 options.macro_mapping_b = true;
1139
1140 let byte = options.to_byte();
1141 assert_eq!(byte & 0b11110001, 0b10010001); let options_from_byte = EncoderOptions::from_byte(byte);
1144 assert!(options_from_byte.enabled);
1145 assert!(options_from_byte.direct_key_mapping_a);
1146 assert!(options_from_byte.macro_mapping_b);
1147 assert!(!options_from_byte.direct_key_mapping_b);
1148 assert!(!options_from_byte.macro_mapping_a);
1149 }
1150
1151 #[test]
1152 fn test_encoder_data_sampling_modes() {
1153 let mut encoder = EncoderData::new();
1154
1155 let options_4x = EncoderOptions::with_4x_sampling();
1157 encoder.set_options(options_4x);
1158 assert!(encoder.is_4x_sampling());
1159 assert!(!encoder.is_2x_sampling());
1160 assert_eq!(encoder.sampling_mode_str(), "4x (both edges)");
1161
1162 let options_2x = EncoderOptions::with_2x_sampling();
1164 encoder.set_options(options_2x);
1165 assert!(!encoder.is_4x_sampling());
1166 assert!(encoder.is_2x_sampling());
1167 assert_eq!(encoder.sampling_mode_str(), "2x (A edges only)");
1168
1169 let options_disabled = EncoderOptions::new();
1171 encoder.set_options(options_disabled);
1172 assert!(!encoder.is_4x_sampling());
1173 assert!(!encoder.is_2x_sampling());
1174 assert_eq!(encoder.sampling_mode_str(), "1x (disabled)");
1175 }
1176
1177 #[test]
1178 fn test_encoder_constants() {
1179 assert_eq!(MAX_ENCODERS, 25);
1180 assert_eq!(MAX_FAST_ENCODERS, 3);
1181 assert_eq!(ULTRA_FAST_ENCODER_INDEX, 25);
1182 }
1183}