stm32g473_hal_oppe/fdcan/
frame.rs1use core::cmp::Ordering;
2
3use super::Id;
4use super::IdReg;
5
6use super::filter::FilterId;
7
8use super::message_ram::enums::FrameFormat as PacFrameFormat;
9use super::message_ram::{RxFifoElementHeader, TxBufferElementHeader};
10
11use super::message_ram::enums::RemoteTransmissionRequest;
12use super::message_ram::enums::{DataLength, FilterFrameMatch};
13
14#[derive(Clone, Copy, Debug, PartialEq)]
16#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
17pub enum FrameFormat {
18 Standard = 0,
20 Fdcan = 1,
22}
23impl From<FrameFormat> for PacFrameFormat {
24 fn from(ff: FrameFormat) -> Self {
25 match ff {
26 FrameFormat::Standard => PacFrameFormat::Standard,
27 FrameFormat::Fdcan => PacFrameFormat::Fdcan,
28 }
29 }
30}
31impl From<PacFrameFormat> for FrameFormat {
32 fn from(ff: PacFrameFormat) -> Self {
33 match ff {
34 PacFrameFormat::Standard => FrameFormat::Standard,
35 PacFrameFormat::Fdcan => FrameFormat::Fdcan,
36 }
37 }
38}
39
40#[derive(Debug, Copy, Clone)]
50#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
51pub struct FramePriority(pub(crate) IdReg);
52
53impl Ord for FramePriority {
56 fn cmp(&self, other: &Self) -> Ordering {
57 self.0.cmp(&other.0)
58 }
59}
60
61impl PartialOrd for FramePriority {
62 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
63 Some(self.cmp(other))
64 }
65}
66
67impl PartialEq for FramePriority {
68 fn eq(&self, other: &Self) -> bool {
69 self.cmp(other) == Ordering::Equal
70 }
71}
72
73impl Eq for FramePriority {}
74
75#[derive(Debug, Copy, Clone)]
77#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
78pub struct TxFrameHeader {
79 pub len: u8,
81 pub frame_format: FrameFormat,
83 pub id: Id,
85 pub bit_rate_switching: bool,
90 pub marker: Option<u8>,
93}
94impl From<TxFrameHeader> for IdReg {
95 fn from(header: TxFrameHeader) -> IdReg {
96 let id: IdReg = header.id.into();
97 id.with_rtr(header.len == 0)
98 }
99}
100
101pub(crate) trait MergeTxFrameHeader {
102 fn merge(&self, header: TxFrameHeader);
103}
104impl MergeTxFrameHeader for TxBufferElementHeader {
105 fn merge(&self, header: TxFrameHeader) {
106 let id: IdReg = header.id.into();
107 self.write(|w| {
108 unsafe { w.id().bits(id.as_raw_id()) }
109 .rtr()
110 .bit(header.len == 0)
111 .xtd()
112 .set_id_type(header.id.into())
113 .set_len(DataLength::new(header.len, header.frame_format.into()))
114 .set_event(header.marker.into())
115 .fdf()
116 .set_format(header.frame_format.into())
117 .brs()
118 .bit(header.bit_rate_switching)
119 });
121 }
122}
123
124impl From<&TxBufferElementHeader> for TxFrameHeader {
125 fn from(reg: &TxBufferElementHeader) -> Self {
126 let reader = reg.read();
127 let id = reader.id().bits();
128 let rtr = reader.rtr().rtr();
129 let xtd = reader.xtd().id_type();
130 let len = reader.to_data_length();
131 let ff: PacFrameFormat = len.into();
132 TxFrameHeader {
133 len: len.len(),
134 frame_format: ff.into(),
135 id: IdReg::from_register(id, rtr, xtd).into(),
136 bit_rate_switching: reader.brs().is_with_brs(),
137 marker: reader.to_event().into(),
139 }
140 }
141}
142
143#[derive(Debug, Copy, Clone)]
145#[cfg_attr(feature = "unstable-defmt", derive(defmt::Format))]
146pub struct RxFrameInfo {
147 pub len: u8,
149 pub frame_format: FrameFormat,
151 pub id: Id,
153 pub rtr: bool,
155 pub filter_match: Option<FilterId>,
157 pub bit_rate_switching: bool,
159 pub time_stamp: u16,
162}
163impl RxFrameInfo {
164 pub fn to_tx_header(self, marker: Option<u8>) -> TxFrameHeader {
166 TxFrameHeader {
167 len: self.len,
168 frame_format: self.frame_format,
169 id: self.id,
170 bit_rate_switching: self.bit_rate_switching,
171 marker,
172 }
173 }
174}
175impl From<&RxFifoElementHeader> for RxFrameInfo {
176 fn from(reg: &RxFifoElementHeader) -> Self {
177 let reader = reg.read();
178 let len = reader.to_data_length();
179 let ff: PacFrameFormat = len.into();
180 let id = reader.id().bits();
181 let rtr = reader.rtr().rtr();
182 let xtd = reader.xtd().id_type();
183 let id = IdReg::from_register(id, rtr, xtd).to_id();
184 let filter = reader.to_filter_match();
185 let filter = match filter {
186 FilterFrameMatch::DidNotMatch => None,
187 FilterFrameMatch::DidMatch(filter) => Some(match id {
188 Id::Standard(_) => FilterId::Standard(filter.into()),
189 Id::Extended(_) => FilterId::Extended(filter.into()),
190 }),
191 };
192 RxFrameInfo {
193 len: len.len(),
194 frame_format: ff.into(),
195 id,
196 rtr: rtr == RemoteTransmissionRequest::TransmitRemoteFrame,
197 filter_match: filter,
198 bit_rate_switching: reader.brs().is_with_brs(),
199 time_stamp: reader.txts().bits(),
200 }
202 }
203}