1use crate::frame::CanFdFrame;
22use crate::resolution::Resolution;
23use crate::scaling::{self, saturate_i16, saturate_i32, saturate_i8, Scaling};
24
25pub const WRITE_INT8: u8 = 0x00;
27pub const WRITE_INT16: u8 = 0x04;
29pub const WRITE_INT32: u8 = 0x08;
31pub const WRITE_FLOAT: u8 = 0x0c;
33
34pub const READ_INT8: u8 = 0x10;
36pub const READ_INT16: u8 = 0x14;
38pub const READ_INT32: u8 = 0x18;
40pub const READ_FLOAT: u8 = 0x1c;
42
43pub const REPLY_INT8: u8 = 0x20;
45pub const REPLY_INT16: u8 = 0x24;
47pub const REPLY_INT32: u8 = 0x28;
49pub const REPLY_FLOAT: u8 = 0x2c;
51
52pub const WRITE_ERROR: u8 = 0x30;
54pub const READ_ERROR: u8 = 0x31;
56
57pub const CLIENT_TO_SERVER: u8 = 0x40;
59pub const SERVER_TO_CLIENT: u8 = 0x41;
61pub const CLIENT_POLL_SERVER: u8 = 0x42;
63
64pub const NOP: u8 = 0x50;
66
67pub struct WriteCanData<'a> {
69 data: &'a mut [u8; 64],
70 size: &'a mut u8,
71}
72
73impl<'a> core::fmt::Debug for WriteCanData<'a> {
74 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75 f.debug_struct("WriteCanData")
76 .field("offset", &(*self.size as usize))
77 .field("remaining", &(64 - *self.size as usize))
78 .finish()
79 }
80}
81
82impl<'a> WriteCanData<'a> {
83 pub fn new(frame: &'a mut CanFdFrame) -> Self {
85 WriteCanData {
86 data: &mut frame.data,
87 size: &mut frame.size,
88 }
89 }
90
91 pub fn from_parts(data: &'a mut [u8; 64], size: &'a mut u8) -> Self {
93 WriteCanData { data, size }
94 }
95
96 pub fn size(&self) -> u8 {
98 *self.size
99 }
100
101 pub fn remaining(&self) -> usize {
103 64 - *self.size as usize
104 }
105
106 pub fn write_u8(&mut self, value: u8) {
108 if (*self.size as usize) < 64 {
109 self.data[*self.size as usize] = value;
110 *self.size += 1;
111 }
112 }
113
114 pub fn write_i8(&mut self, value: i8) {
116 self.write_u8(value as u8);
117 }
118
119 pub fn write_i16(&mut self, value: i16) {
121 let bytes = value.to_le_bytes();
122 self.write_bytes(&bytes);
123 }
124
125 pub fn write_i32(&mut self, value: i32) {
127 let bytes = value.to_le_bytes();
128 self.write_bytes(&bytes);
129 }
130
131 pub fn write_f32(&mut self, value: f32) {
133 let bytes = value.to_le_bytes();
134 self.write_bytes(&bytes);
135 }
136
137 pub fn write_bytes(&mut self, bytes: &[u8]) {
139 let start = *self.size as usize;
140 let end = start + bytes.len();
141 if end <= 64 {
142 self.data[start..end].copy_from_slice(bytes);
143 *self.size = end as u8;
144 }
145 }
146
147 pub fn write_varuint(&mut self, mut value: u32) {
149 loop {
150 let mut this_byte = (value & 0x7f) as u8;
151 value >>= 7;
152 if value != 0 {
153 this_byte |= 0x80;
154 }
155 self.write_u8(this_byte);
156 if value == 0 {
157 break;
158 }
159 }
160 }
161
162 pub fn write_int(&mut self, value: i32, res: Resolution) {
164 match res {
165 Resolution::Int8 => {
166 let clamped = value.clamp(-127, 127) as i8;
167 self.write_i8(clamped);
168 }
169 Resolution::Int16 => {
170 let clamped = value.clamp(-32767, 32767) as i16;
171 self.write_i16(clamped);
172 }
173 Resolution::Int32 => {
174 self.write_i32(value);
175 }
176 Resolution::Float => {
177 self.write_f32(value as f32);
178 }
179 Resolution::Ignore => {}
180 }
181 }
182
183 pub fn write_mapped(&mut self, value: f32, scaling: &Scaling, res: Resolution) {
185 match res {
186 Resolution::Int8 => {
187 self.write_i8(saturate_i8(value, scaling.int8));
188 }
189 Resolution::Int16 => {
190 self.write_i16(saturate_i16(value, scaling.int16));
191 }
192 Resolution::Int32 => {
193 self.write_i32(saturate_i32(value, scaling.int32));
194 }
195 Resolution::Float => {
196 self.write_f32(value);
197 }
198 Resolution::Ignore => {}
199 }
200 }
201
202 pub fn write_position(&mut self, value: f32, res: Resolution) {
206 self.write_mapped(value, &scaling::POSITION, res);
207 }
208
209 pub fn write_velocity(&mut self, value: f32, res: Resolution) {
211 self.write_mapped(value, &scaling::VELOCITY, res);
212 }
213
214 pub fn write_accel(&mut self, value: f32, res: Resolution) {
216 self.write_mapped(value, &scaling::ACCELERATION, res);
217 }
218
219 pub fn write_torque(&mut self, value: f32, res: Resolution) {
221 self.write_mapped(value, &scaling::TORQUE, res);
222 }
223
224 pub fn write_pwm(&mut self, value: f32, res: Resolution) {
226 self.write_mapped(value, &scaling::PWM, res);
227 }
228
229 pub fn write_voltage(&mut self, value: f32, res: Resolution) {
231 self.write_mapped(value, &scaling::VOLTAGE, res);
232 }
233
234 pub fn write_temperature(&mut self, value: f32, res: Resolution) {
236 self.write_mapped(value, &scaling::TEMPERATURE, res);
237 }
238
239 pub fn write_time(&mut self, value: f32, res: Resolution) {
241 self.write_mapped(value, &scaling::TIME, res);
242 }
243
244 pub fn write_current(&mut self, value: f32, res: Resolution) {
246 self.write_mapped(value, &scaling::CURRENT, res);
247 }
248}
249
250pub struct WriteCombiner<'a> {
256 base_command: u8,
257 start_register: u16,
258 resolutions: &'a [Resolution],
259 current_resolution: Resolution,
260 offset: usize,
261 reply_size: u8,
262}
263
264impl<'a> core::fmt::Debug for WriteCombiner<'a> {
265 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
266 f.debug_struct("WriteCombiner")
267 .field("base_command", &self.base_command)
268 .field("start_register", &self.start_register)
269 .field("offset", &self.offset)
270 .field("current_resolution", &self.current_resolution)
271 .field("reply_size", &self.reply_size)
272 .finish()
273 }
274}
275
276impl<'a> WriteCombiner<'a> {
277 pub fn new(base_command: u8, start_register: u16, resolutions: &'a [Resolution]) -> Self {
284 WriteCombiner {
285 base_command,
286 start_register,
287 resolutions,
288 current_resolution: Resolution::Ignore,
289 offset: 0,
290 reply_size: 0,
291 }
292 }
293
294 pub fn reply_size(&self) -> u8 {
296 self.reply_size
297 }
298
299 pub fn maybe_write(&mut self, frame: &mut WriteCanData) -> bool {
304 let this_offset = self.offset;
305 self.offset += 1;
306
307 if this_offset >= self.resolutions.len() {
308 return false;
309 }
310
311 let new_resolution = self.resolutions[this_offset];
312
313 if self.current_resolution == new_resolution {
315 return new_resolution != Resolution::Ignore;
316 }
317
318 self.current_resolution = new_resolution;
320
321 if new_resolution == Resolution::Ignore {
323 return false;
324 }
325
326 let mut count = 1i16;
328 for i in (this_offset + 1)..self.resolutions.len() {
329 if self.resolutions[i] == new_resolution {
330 count += 1;
331 } else {
332 break;
333 }
334 }
335
336 let write_command = self.base_command + new_resolution.type_code();
338
339 let start_size = frame.size();
340
341 if count <= 3 {
342 frame.write_u8(write_command + count as u8);
344 } else {
345 frame.write_u8(write_command);
347 frame.write_u8(count as u8);
348 }
349
350 frame.write_varuint((self.start_register + this_offset as u16) as u32);
352
353 let end_size = frame.size();
354
355 self.reply_size += end_size - start_size;
357 self.reply_size += (count as u8) * (new_resolution.size() as u8);
358
359 true
360 }
361}
362
363#[non_exhaustive]
365#[derive(Debug, Clone, Copy)]
366pub enum Value {
367 Int8(i8),
369 Int16(i16),
371 Int32(i32),
373 Float(f32),
375}
376
377impl Value {
378 pub fn to_i32(&self) -> i32 {
384 match *self {
385 Value::Int8(v) => v as i32,
386 Value::Int16(v) => v as i32,
387 Value::Int32(v) => v,
388 Value::Float(v) => v as i32,
389 }
390 }
391
392 pub fn to_f32(&self, scaling: &Scaling) -> f32 {
409 use crate::scaling::{nanify_i16, nanify_i32, nanify_i8};
410
411 match *self {
412 Value::Int8(v) => nanify_i8(v) * scaling.int8,
413 Value::Int16(v) => nanify_i16(v) * scaling.int16,
414 Value::Int32(v) => nanify_i32(v) * scaling.int32,
415 Value::Float(v) => v,
416 }
417 }
418}
419
420#[non_exhaustive]
422#[derive(Debug, Clone, Copy, PartialEq, Eq)]
423pub enum SubframeType {
424 Write,
426 Read,
428 Response,
430 WriteError,
432 ReadError,
434 StreamClientToServer,
436 StreamServerToClient,
438 StreamClientPollServer,
440}
441
442#[non_exhaustive]
444#[derive(Debug, Clone)]
445pub enum Subframe<'a> {
446 Register {
448 subframe_type: SubframeType,
450 register: u16,
452 resolution: Resolution,
454 value: Option<Value>,
456 },
457 Error {
459 subframe_type: SubframeType,
461 register: u16,
463 error_code: u16,
465 },
466 Stream {
468 subframe_type: SubframeType,
470 channel: u16,
472 data: &'a [u8],
474 },
475}
476
477pub struct FrameParser<'a> {
484 data: &'a [u8],
485 offset: usize,
486 remaining: u16,
487 current_register: u16,
488 current_resolution: Resolution,
489 current_type: SubframeType,
490}
491
492impl<'a> core::fmt::Debug for FrameParser<'a> {
493 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
494 f.debug_struct("FrameParser")
495 .field("data_len", &self.data.len())
496 .field("offset", &self.offset)
497 .field("remaining", &self.remaining)
498 .field("current_register", &self.current_register)
499 .field("current_resolution", &self.current_resolution)
500 .field("current_type", &self.current_type)
501 .finish()
502 }
503}
504
505impl<'a> FrameParser<'a> {
506 pub fn new(data: &'a [u8]) -> Self {
508 FrameParser {
509 data,
510 offset: 0,
511 remaining: 0,
512 current_register: 0,
513 current_resolution: Resolution::Ignore,
514 current_type: SubframeType::Response,
515 }
516 }
517
518 pub fn from_frame(frame: &'a CanFdFrame) -> Self {
520 Self::new(&frame.data[..frame.size as usize])
521 }
522
523 fn read_varuint(&mut self) -> u16 {
525 let mut result: u16 = 0;
526 let mut shift = 0;
527
528 for _ in 0..5 {
529 if self.offset >= self.data.len() {
530 return result;
531 }
532
533 let byte = self.data[self.offset];
534 self.offset += 1;
535
536 result |= ((byte & 0x7f) as u16) << shift;
537 shift += 7;
538
539 if byte & 0x80 == 0 {
540 return result;
541 }
542 }
543
544 result
545 }
546
547 fn read_value(&mut self, res: Resolution) -> Option<Value> {
549 match res {
550 Resolution::Int8 => {
551 if self.offset < self.data.len() {
552 let v = self.data[self.offset] as i8;
553 self.offset += 1;
554 Some(Value::Int8(v))
555 } else {
556 None
557 }
558 }
559 Resolution::Int16 => {
560 if self.offset + 2 <= self.data.len() {
561 let bytes = [self.data[self.offset], self.data[self.offset + 1]];
562 self.offset += 2;
563 Some(Value::Int16(i16::from_le_bytes(bytes)))
564 } else {
565 None
566 }
567 }
568 Resolution::Int32 => {
569 if self.offset + 4 <= self.data.len() {
570 let bytes = [
571 self.data[self.offset],
572 self.data[self.offset + 1],
573 self.data[self.offset + 2],
574 self.data[self.offset + 3],
575 ];
576 self.offset += 4;
577 Some(Value::Int32(i32::from_le_bytes(bytes)))
578 } else {
579 None
580 }
581 }
582 Resolution::Float => {
583 if self.offset + 4 <= self.data.len() {
584 let bytes = [
585 self.data[self.offset],
586 self.data[self.offset + 1],
587 self.data[self.offset + 2],
588 self.data[self.offset + 3],
589 ];
590 self.offset += 4;
591 Some(Value::Float(f32::from_le_bytes(bytes)))
592 } else {
593 None
594 }
595 }
596 Resolution::Ignore => None,
597 }
598 }
599
600 fn next_from_block(&mut self) -> Option<Subframe<'a>> {
602 if self.remaining == 0 {
603 return None;
604 }
605
606 self.remaining -= 1;
607 let register = self.current_register;
608 self.current_register += 1;
609
610 if self.current_type == SubframeType::Read {
612 return Some(Subframe::Register {
613 subframe_type: self.current_type,
614 register,
615 resolution: self.current_resolution,
616 value: None,
617 });
618 }
619
620 let value = self.read_value(self.current_resolution);
622 if value.is_none() {
623 self.offset = self.data.len();
625 self.remaining = 0;
626 return None;
627 }
628
629 Some(Subframe::Register {
630 subframe_type: self.current_type,
631 register,
632 resolution: self.current_resolution,
633 value,
634 })
635 }
636
637 fn parse_register_block(&mut self, cmd: u8) -> Option<Subframe<'a>> {
639 let family = cmd & 0xf0;
640 let subframe_type = match family {
641 0x00 => SubframeType::Write,
642 0x10 => SubframeType::Read,
643 0x20 => SubframeType::Response,
644 _ => return None,
645 };
646
647 let resolution = match (cmd >> 2) & 0x03 {
648 0 => Resolution::Int8,
649 1 => Resolution::Int16,
650 2 => Resolution::Int32,
651 3 => Resolution::Float,
652 _ => Resolution::Int8,
653 };
654
655 let mut count = (cmd & 0x03) as u16;
656 if count == 0 {
657 if self.offset >= self.data.len() {
658 return None;
659 }
660 count = self.data[self.offset] as u16;
661 self.offset += 1;
662 }
663
664 if count == 0 {
665 return None;
666 }
667
668 let register = self.read_varuint();
669
670 self.current_type = subframe_type;
671 self.current_resolution = resolution;
672 self.current_register = register + 1;
673 self.remaining = count - 1;
674
675 if subframe_type == SubframeType::Read {
677 return Some(Subframe::Register {
678 subframe_type,
679 register,
680 resolution,
681 value: None,
682 });
683 }
684
685 let value = self.read_value(resolution);
687 if value.is_none() {
688 self.offset = self.data.len();
689 self.remaining = 0;
690 return None;
691 }
692
693 Some(Subframe::Register {
694 subframe_type,
695 register,
696 resolution,
697 value,
698 })
699 }
700
701 fn parse_error(&mut self, cmd: u8) -> Option<Subframe<'a>> {
703 let subframe_type = match cmd {
704 WRITE_ERROR => SubframeType::WriteError,
705 READ_ERROR => SubframeType::ReadError,
706 _ => return None,
707 };
708
709 let register = self.read_varuint();
710 let error_code = self.read_varuint();
711
712 Some(Subframe::Error {
713 subframe_type,
714 register,
715 error_code,
716 })
717 }
718
719 fn parse_stream(&mut self, cmd: u8) -> Option<Subframe<'a>> {
721 let subframe_type = match cmd {
722 CLIENT_TO_SERVER => SubframeType::StreamClientToServer,
723 SERVER_TO_CLIENT => SubframeType::StreamServerToClient,
724 CLIENT_POLL_SERVER => SubframeType::StreamClientPollServer,
725 _ => return None,
726 };
727
728 let channel = self.read_varuint();
729 let size = self.read_varuint() as usize;
730
731 if self.offset + size > self.data.len() {
732 self.offset = self.data.len();
733 return None;
734 }
735
736 let data = &self.data[self.offset..self.offset + size];
737 self.offset += size;
738
739 Some(Subframe::Stream {
740 subframe_type,
741 channel,
742 data,
743 })
744 }
745}
746
747impl<'a> Iterator for FrameParser<'a> {
748 type Item = Subframe<'a>;
749
750 fn next(&mut self) -> Option<Subframe<'a>> {
751 if self.remaining > 0 {
753 return self.next_from_block();
754 }
755
756 while self.offset < self.data.len() {
758 let cmd = self.data[self.offset];
759 self.offset += 1;
760
761 if cmd == NOP {
763 continue;
764 }
765
766 match cmd & 0xf0 {
767 0x00 | 0x10 | 0x20 => {
769 if let Some(subframe) = self.parse_register_block(cmd) {
770 return Some(subframe);
771 }
772 continue;
774 }
775 0x30 => {
777 if let Some(subframe) = self.parse_error(cmd) {
778 return Some(subframe);
779 }
780 continue;
781 }
782 0x40 => {
784 if let Some(subframe) = self.parse_stream(cmd) {
785 return Some(subframe);
786 }
787 continue;
788 }
789 _ => {
791 self.offset = self.data.len();
792 return None;
793 }
794 }
795 }
796
797 None
798 }
799}
800
801pub fn parse_frame(data: &[u8]) -> FrameParser<'_> {
820 FrameParser::new(data)
821}
822
823#[cfg(test)]
824mod tests {
825 use super::*;
826
827 #[test]
828 fn test_write_varuint() {
829 let mut frame = CanFdFrame::new();
831 {
832 let mut writer = WriteCanData::new(&mut frame);
833 writer.write_varuint(0);
834 }
835 assert_eq!(frame.data[0], 0x00);
836 assert_eq!(frame.size, 1);
837
838 frame.size = 0;
840 {
841 let mut writer = WriteCanData::new(&mut frame);
842 writer.write_varuint(127);
843 }
844 assert_eq!(frame.data[0], 0x7f);
845
846 frame.size = 0;
848 {
849 let mut writer = WriteCanData::new(&mut frame);
850 writer.write_varuint(128);
851 }
852 assert_eq!(frame.data[0], 0x80);
853 assert_eq!(frame.data[1], 0x01);
854 assert_eq!(frame.size, 2);
855 }
856
857 #[test]
858 fn test_write_combiner() {
859 let mut frame = CanFdFrame::new();
860 let mut writer = WriteCanData::new(&mut frame);
861
862 let resolutions = [Resolution::Float, Resolution::Float, Resolution::Ignore];
863 let mut combiner = WriteCombiner::new(0x00, 0x020, &resolutions);
864
865 assert!(combiner.maybe_write(&mut writer));
867 writer.write_f32(1.0);
868 assert!(combiner.maybe_write(&mut writer));
870 writer.write_f32(2.0);
871 assert!(!combiner.maybe_write(&mut writer));
873
874 assert_eq!(frame.size, 10); assert_eq!(frame.data[0], 0x0e);
879 assert_eq!(frame.data[1], 0x20);
880 assert_eq!(
881 f32::from_le_bytes(frame.data[2..6].try_into().unwrap()),
882 1.0
883 );
884 assert_eq!(
885 f32::from_le_bytes(frame.data[6..10].try_into().unwrap()),
886 2.0
887 );
888
889 assert_eq!(combiner.reply_size(), 10);
891 }
892
893 #[test]
894 fn test_parser_basic() {
895 let data = [
897 0x21, 0x00, 0x0a, ];
901
902 let mut iter = parse_frame(&data);
903
904 let subframe = iter.next().unwrap();
905 match subframe {
906 Subframe::Register {
907 subframe_type,
908 register,
909 resolution,
910 value,
911 } => {
912 assert_eq!(subframe_type, SubframeType::Response);
913 assert_eq!(register, 0);
914 assert_eq!(resolution, Resolution::Int8);
915 assert_eq!(value.unwrap().to_i32(), 10);
916 }
917 _ => panic!("Expected Register subframe"),
918 }
919
920 assert!(iter.next().is_none());
921 }
922
923 #[test]
924 fn test_parser_write_subframes() {
925 let data = [
927 0x06, 0x20, 0x64, 0x00, 0xc8, 0x00, ];
932
933 let mut iter = parse_frame(&data);
934
935 match iter.next().unwrap() {
936 Subframe::Register {
937 subframe_type,
938 register,
939 resolution,
940 value,
941 } => {
942 assert_eq!(subframe_type, SubframeType::Write);
943 assert_eq!(register, 0x20);
944 assert_eq!(resolution, Resolution::Int16);
945 assert_eq!(value.unwrap().to_i32(), 100);
946 }
947 _ => panic!("Expected Register subframe"),
948 }
949
950 match iter.next().unwrap() {
951 Subframe::Register {
952 subframe_type,
953 register,
954 value,
955 ..
956 } => {
957 assert_eq!(subframe_type, SubframeType::Write);
958 assert_eq!(register, 0x21);
959 assert_eq!(value.unwrap().to_i32(), 200);
960 }
961 _ => panic!("Expected Register subframe"),
962 }
963
964 assert!(iter.next().is_none());
965 }
966
967 #[test]
968 fn test_parser_read_subframes() {
969 let data = [
971 0x1d, 0x05, ];
974
975 let mut iter = parse_frame(&data);
976
977 match iter.next().unwrap() {
978 Subframe::Register {
979 subframe_type,
980 register,
981 resolution,
982 value,
983 } => {
984 assert_eq!(subframe_type, SubframeType::Read);
985 assert_eq!(register, 5);
986 assert_eq!(resolution, Resolution::Float);
987 assert!(value.is_none());
988 }
989 _ => panic!("Expected Register subframe"),
990 }
991
992 assert!(iter.next().is_none());
993 }
994
995 #[test]
996 fn test_parser_nop_skipped() {
997 let data = [
998 0x50, 0x21, 0x00, 0x05, ];
1003
1004 let mut iter = parse_frame(&data);
1005
1006 match iter.next().unwrap() {
1007 Subframe::Register {
1008 register, value, ..
1009 } => {
1010 assert_eq!(register, 0);
1011 assert_eq!(value.unwrap().to_i32(), 5);
1012 }
1013 _ => panic!("Expected Register subframe"),
1014 }
1015
1016 assert!(iter.next().is_none());
1017 }
1018
1019 #[test]
1020 fn test_parser_multiple_blocks() {
1021 let data = [0x21, 0x00, 0x0a, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x3f];
1023
1024 let mut iter = parse_frame(&data);
1025
1026 match iter.next().unwrap() {
1027 Subframe::Register {
1028 register, value, ..
1029 } => {
1030 assert_eq!(register, 0);
1031 assert_eq!(value.unwrap().to_i32(), 10);
1032 }
1033 _ => panic!("Expected Register subframe"),
1034 }
1035
1036 match iter.next().unwrap() {
1037 Subframe::Register {
1038 register, value, ..
1039 } => {
1040 assert_eq!(register, 1);
1041 let val = match value.unwrap() {
1042 Value::Float(f) => f,
1043 _ => panic!("Expected Float"),
1044 };
1045 assert!((val - 0.5).abs() < 0.001);
1046 }
1047 _ => panic!("Expected Register subframe"),
1048 }
1049
1050 assert!(iter.next().is_none());
1051 }
1052
1053 #[test]
1054 fn test_value_to_f32() {
1055 let v = Value::Int8(50);
1057 assert!((v.to_f32(&scaling::POSITION) - 0.5).abs() < 1e-5);
1058
1059 let v = Value::Int8(i8::MIN);
1061 assert!(v.to_f32(&scaling::POSITION).is_nan());
1062
1063 let v = Value::Float(1.5);
1065 assert!((v.to_f32(&scaling::POSITION) - 1.5).abs() < 1e-5);
1066 }
1067}