Skip to content

Commit

Permalink
Merge pull request #78 from Northeastern-Electric-Racing/feature/ieee…
Browse files Browse the repository at this point in the history
…754-f32

Added support to decode IEEE754 32-bit floats over CAN
  • Loading branch information
harrison-e authored Dec 10, 2024
2 parents 7098457 + ab74f81 commit 415f002
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 24 deletions.
53 changes: 30 additions & 23 deletions libs/calypso-cangen/src/can_gen_decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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::<LittleEndian, #read_type>().unwrap() as f32)
reader.read_as_to::<LittleEndian, #read_type>().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) },
}
}
}
5 changes: 5 additions & 0 deletions libs/calypso-cangen/src/can_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -38,6 +42,7 @@ pub struct CANPoint {
pub endianness: Option<String>,
pub format: Option<String>,
pub default_value: Option<f32>,
pub ieee754_f32: Option<bool>,
}

#[derive(Deserialize, Debug)]
Expand Down

0 comments on commit 415f002

Please sign in to comment.