-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add standard id support & testing of pgn
- Loading branch information
Jannes Brands
committed
Feb 15, 2024
1 parent
2133ea4
commit e9e8d1e
Showing
8 changed files
with
285 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Copyright 2023 Raven Industries inc. | ||
use crate::j1939::id::{Id, ParseIdError}; | ||
use crate::j1939::priority::Priority; | ||
use crate::j1939::standard_id::StandardId; | ||
use crate::j1939::{Address, Pgn}; | ||
use bitvec::field::BitField; | ||
use bitvec::order::Msb0; | ||
use bitvec::vec::BitVec; | ||
use bitvec::view::BitView; | ||
use embedded_can::{ExtendedId as EmbeddedExtendedId, Id as EmbeddedId}; | ||
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] | ||
pub struct ExtendedId { | ||
standard_id: StandardId, | ||
pgn: Pgn, | ||
} | ||
|
||
impl ExtendedId { | ||
pub fn new(standard_id: StandardId, pgn: Pgn) -> Self { | ||
Self { standard_id, pgn } | ||
} | ||
|
||
/// Get the raw value of the CAN ID | ||
#[inline] | ||
pub fn raw(&self) -> u32 { | ||
let mut raw_id: BitVec<u32> = BitVec::new(); | ||
raw_id.append( | ||
&mut (self.standard_id.priority() as u8) | ||
.view_bits_mut::<Msb0>() | ||
.to_bitvec(), | ||
); | ||
raw_id.append(&mut self.pgn.raw()); | ||
raw_id.append( | ||
&mut self | ||
.standard_id | ||
.source_address() | ||
.raw() | ||
.view_bits::<Msb0>() | ||
.to_bitvec(), | ||
); | ||
raw_id.load::<u32>() | ||
} | ||
|
||
/// Get the PGN of the ID | ||
#[inline] | ||
pub fn pgn(&self) -> Pgn { | ||
self.pgn | ||
} | ||
} | ||
|
||
impl From<ExtendedId> for EmbeddedId { | ||
fn from(id: ExtendedId) -> Self { | ||
EmbeddedId::Extended(EmbeddedExtendedId::new(id.raw()).unwrap_or(EmbeddedExtendedId::ZERO)) | ||
} | ||
} | ||
|
||
impl TryFrom<EmbeddedId> for ExtendedId { | ||
type Error = ParseIdError; | ||
|
||
fn try_from(value: EmbeddedId) -> Result<Self, Self::Error> { | ||
match value { | ||
EmbeddedId::Standard(_) => Err(ParseIdError::StandardId), | ||
EmbeddedId::Extended(id) => { | ||
let bit_data = id.as_raw().view_bits::<Msb0>().to_bitvec(); | ||
let priority = Priority::try_from(bit_data.load::<u8>()); | ||
let pgn = Pgn::try_from(bit_data.load::<u32>()); | ||
let source_address = Address::new(bit_data.load::<u8>()); | ||
|
||
if priority.is_err() { | ||
return Err(ParseIdError::Priority); | ||
} | ||
|
||
if pgn.is_err() { | ||
return Err(ParseIdError::Pgn); | ||
} | ||
|
||
Ok(ExtendedId::new( | ||
StandardId::new(priority.unwrap(), source_address), | ||
pgn.unwrap(), | ||
)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl TryFrom<u32> for ExtendedId { | ||
type Error = ParseIdError; | ||
|
||
fn try_from(raw_id: u32) -> Result<Self, Self::Error> { | ||
let bit_data = raw_id.view_bits::<Msb0>().to_bitvec(); | ||
let priority = Priority::try_from(bit_data.load::<u8>()); | ||
let pgn = Pgn::try_from(bit_data.load::<u32>()); | ||
let source_address = Address::new(bit_data.load::<u8>()); | ||
|
||
if priority.is_err() || pgn.is_err() { | ||
return Err(ParseIdError::Priority); | ||
} | ||
|
||
Ok(ExtendedId::new( | ||
StandardId::new(priority.unwrap(), source_address), | ||
pgn.unwrap(), | ||
)) | ||
} | ||
} | ||
|
||
impl From<ExtendedId> for Id { | ||
fn from(id: ExtendedId) -> Self { | ||
Id::Extended(id) | ||
} | ||
} | ||
|
||
//TODO: tests -> especially for 'bit_data.load::<u32>()' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,23 @@ | ||
use bitvec::field::BitField; | ||
use bitvec::order::Msb0; | ||
use bitvec::vec::BitVec; | ||
use bitvec::view::BitView; | ||
// Copyright 2023 Raven Industries inc. | ||
use crate::j1939::priority::Priority; | ||
use crate::j1939::{Address, Pgn}; | ||
use embedded_can::{ExtendedId, Id as EmbeddedId}; | ||
use crate::j1939::standard_id::StandardId; | ||
use crate::j1939::ExtendedId; | ||
|
||
#[derive(Debug)] | ||
pub enum ParseIdError { | ||
Priority, | ||
Pgn, | ||
SourceAddress, | ||
StandardId, | ||
ExtendedId, | ||
} | ||
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] | ||
pub struct Id { | ||
priority: Priority, | ||
pgn: Pgn, | ||
source_address: Address, | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
pub enum Id { | ||
Standard(StandardId), | ||
Extended(ExtendedId), | ||
} | ||
|
||
impl Id { | ||
pub fn new(priority: Priority, pgn: Pgn, source_address: Address) -> Self { | ||
Self { | ||
priority, | ||
pgn, | ||
source_address, | ||
} | ||
} | ||
|
||
/// Get the raw value of the CAN ID | ||
#[inline] | ||
pub fn raw(&self) -> u32 { | ||
let mut raw_id: BitVec<u32> = BitVec::new(); | ||
raw_id.append(&mut (self.priority as u8).view_bits_mut::<Msb0>().to_bitvec()); | ||
raw_id.append(&mut self.pgn.raw()); | ||
raw_id.append(&mut self.source_address.raw().view_bits::<Msb0>().to_bitvec()); | ||
raw_id.load::<u32>() | ||
} | ||
|
||
/// Get the priority of the ID | ||
#[inline] | ||
pub fn priority(&self) -> Priority { | ||
self.priority | ||
} | ||
|
||
/// Get the source address of the ID | ||
#[inline] | ||
pub fn source_address(&self) -> Address { | ||
self.source_address | ||
} | ||
|
||
/// Get the PGN of the ID | ||
#[inline] | ||
pub fn pgn(&self) -> Pgn { | ||
self.pgn | ||
} | ||
} | ||
|
||
impl From<Id> for EmbeddedId { | ||
fn from(id: Id) -> Self { | ||
EmbeddedId::Extended(ExtendedId::new(id.raw()).unwrap_or(ExtendedId::ZERO)) | ||
impl Default for Id { | ||
fn default() -> Self { | ||
Id::Extended(ExtendedId::default()) | ||
} | ||
} | ||
|
||
impl TryFrom<EmbeddedId> for Id { | ||
type Error = ParseIdError; | ||
|
||
fn try_from(value: EmbeddedId) -> Result<Self, Self::Error> { | ||
match value { | ||
EmbeddedId::Standard(_) => Err(ParseIdError::Pgn), | ||
EmbeddedId::Extended(id) => { | ||
let bit_data = id.as_raw().view_bits::<Msb0>().to_bitvec(); | ||
let priority = Priority::try_from(bit_data.load::<u8>()); | ||
let pgn = Pgn::try_from(bit_data.load::<u32>()); | ||
let source_address = Address::new(bit_data.load::<u8>()); | ||
|
||
if priority.is_err() { | ||
return Err(ParseIdError::Priority); | ||
} | ||
|
||
if pgn.is_err() { | ||
return Err(ParseIdError::Pgn); | ||
} | ||
|
||
Ok(Id::new(priority.unwrap(), pgn.unwrap(), source_address)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl TryFrom<u32> for Id { | ||
type Error = ParseIdError; | ||
|
||
fn try_from(raw_id: u32) -> Result<Self, Self::Error> { | ||
let bit_data = raw_id.view_bits::<Msb0>().to_bitvec(); | ||
let priority = Priority::try_from(bit_data.load::<u8>()); | ||
let pgn = Pgn::try_from(bit_data.load::<u32>()); | ||
let source_address = Address::new(bit_data.load::<u8>()); | ||
|
||
if priority.is_err() || pgn.is_err() { | ||
return Err(ParseIdError::Priority); | ||
} | ||
|
||
Ok(Id::new(priority.unwrap(), pgn.unwrap(), source_address)) | ||
} | ||
} | ||
|
||
//TODO: tests -> especially for 'bit_data.load::<u32>()' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use bitvec::field::BitField; | ||
use bitvec::order::Msb0; | ||
use bitvec::prelude::BitVec; | ||
|
||
#[derive(Debug)] | ||
enum ParsePageError { | ||
InvalidPage(u8), | ||
} | ||
|
||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
#[repr(u8)] | ||
pub enum Page { | ||
J1939Page0 = 0, | ||
J1939Page1 = 1, | ||
J1939PageReserved = 2, | ||
ISO11992_4 = 3, | ||
} | ||
|
||
impl TryFrom<u8> for Page { | ||
type Error = ParsePageError; | ||
|
||
fn try_from(raw_page: u8) -> Result<Self, Self::Error> { | ||
match raw_page { | ||
0x0 => Ok(Page::J1939Page0), | ||
0x1 => Ok(Page::J1939Page1), | ||
0x2 => Ok(Page::J1939PageReserved), | ||
0x3 => Ok(Page::ISO11992_4), | ||
_ => Err(ParsePageError::InvalidPage(raw_page)), | ||
} | ||
} | ||
} | ||
|
||
impl From<[bool; 2]> for Page { | ||
fn from(value: [bool; 2]) -> Self { | ||
let mut page_vec: BitVec<u8, Msb0> = BitVec::new(); | ||
page_vec.resize(8, false); | ||
page_vec[0] = value[0]; | ||
page_vec[1] = value[1]; | ||
Page::try_from(page_vec.load::<u8>()).unwrap() | ||
} | ||
} |
Oops, something went wrong.