diff --git a/Embedded-Base b/Embedded-Base index 40f07ee..5d4b634 160000 --- a/Embedded-Base +++ b/Embedded-Base @@ -1 +1 @@ -Subproject commit 40f07ee0d15ad984d5a9e5c3d31cbae41fec5fc1 +Subproject commit 5d4b634132fa9dc44e4f9496c265c6e214715075 diff --git a/libs/calypso-cangen/src/can_gen_decode.rs b/libs/calypso-cangen/src/can_gen_decode.rs index 12eb33a..b369d8f 100644 --- a/libs/calypso-cangen/src/can_gen_decode.rs +++ b/libs/calypso-cangen/src/can_gen_decode.rs @@ -141,26 +141,26 @@ impl CANGenDecode for NetField { */ impl CANGenDecode for CANPoint { fn gen_decoder_fn(&mut self) -> ProcMacro2TokenStream { - // read_func and read_type to map signedness (read_func for big endian, read_type for little endian) let size_literal = Literal::usize_unsuffixed(self.size); - let read_func = match self.signed { - Some(true) => quote! { reader.read_signed_in::<#size_literal, i32>().unwrap() }, - _ => quote! { reader.read_in::<#size_literal, u32>().unwrap() }, - }; - let read_type = match self.signed { - Some(true) => match self.size { - 0..=8 => quote! { i8 }, - 9..=16 => quote! { i16 }, - _ => quote! { i32 }, - }, - _ => match self.size { - 0..=8 => quote! { u8 }, - 9..=16 => quote! { u16 }, - _ => quote! { u32 }, + + // If this point is an IEEE754 f32, always read it as a u32, and transmute to f32 later + let read_type = match self.ieee754_f32 { + Some(true) => quote! { u32 }, + _ => match self.signed { + Some(true) => match self.size { + 0..=8 => quote! { i8 }, + 9..=16 => quote! { i16 }, + _ => quote! { i32 }, + }, + _ => match self.size { + 0..=8 => quote! { u8 }, + 9..=16 => quote! { u16 }, + _ => quote! { u32 }, + }, }, }; - // prefix to call potential format function + // Prefix to call potential format function let format_prefix = match &self.format { Some(format) => { let id = format_ident!("{}_d", format); @@ -169,18 +169,25 @@ impl CANGenDecode for CANPoint { _ => quote! {}, }; - // Endianness affects which read to use - match self.endianness { + // Endianness and signedness affect which read to use + let read_func = match self.endianness { Some(ref s) if s == "little" => { quote! { - #format_prefix (reader.read_as_to::().unwrap() as f32) + reader.read_as_to::().unwrap() } } - _ => { - quote! { - #format_prefix (#read_func as f32) + _ => match self.signed { + Some(true) if self.ieee754_f32.is_none() => { + quote! { reader.read_signed_in::<#size_literal, i32>().unwrap() } } - } + _ => quote! { reader.read_in::<#size_literal, u32>().unwrap() }, + }, + }; + + // Transmute if point is IEEE754 f32, else convert + match self.ieee754_f32 { + Some(true) => quote! { #format_prefix (f32::from_bits(#read_func)) }, + _ => quote! { #format_prefix (#read_func as f32) }, } } } diff --git a/libs/calypso-cangen/src/can_types.rs b/libs/calypso-cangen/src/can_types.rs index 8b367f2..242e3aa 100644 --- a/libs/calypso-cangen/src/can_types.rs +++ b/libs/calypso-cangen/src/can_types.rs @@ -2,6 +2,10 @@ use serde::Deserialize; // TODO: Implement MsgType +// Classes to represent levels of the CAN hierarchy +// For more specific descriptions, refer to the README +// in Embedded-Base/cangen + /** * Class representing a CAN message */ @@ -38,6 +42,7 @@ pub struct CANPoint { pub endianness: Option, pub format: Option, pub default_value: Option, + pub ieee754_f32: Option, } #[derive(Deserialize, Debug)]