1use bincode::{
17 Decode, Encode,
18 config::Configuration,
19 error::{DecodeError, EncodeError},
20};
21use defmt::*;
22use embassy_stm32::can::{BufferedCanFd, Can, Frame, frame::FdFrame};
23use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex};
24use embassy_time::Timer;
25use embedded_can::Id;
26
27use crate::eco_can::{
28 ECOCAN_H2Pack1_t, ECOCAN_H2Pack2_t, FDCAN_BOOSTPack1_t, FDCAN_BOOSTPack2_t, FDCAN_BOOSTPack3_t,
29 FDCAN_FccPack1_t, FDCAN_FccPack2_t, FDCAN_FccPack3_t, FDCAN_FetPack_t, FDCAN_RelPackCap_t,
30 FDCAN_RelPackFc_t, FDCAN_RelPackMtr_t, FDCANPack, RelayState,
31};
32
33pub const TX_BUF_SIZE: usize = 1;
35pub const RX_BUF_SIZE: usize = 20;
37
38const BINCODE_CONFIG: Configuration<bincode::config::BigEndian, bincode::config::Fixint> =
39 bincode::config::standard()
40 .with_big_endian()
41 .with_fixed_int_encoding();
42
43pub static RELAY_STATE: Mutex<ThreadModeRawMutex, RelayState> = Mutex::new(RelayState::RELAY_STRTP);
44
45pub static FET_DATA: Mutex<ThreadModeRawMutex, FDCAN_FetPack_t> = Mutex::new(FDCAN_FetPack_t {
46 fet_config: 0,
47 input_volt: 0,
48 cap_volt: 0,
49 cap_curr: 0,
50 res_curr: 0,
51 out_curr: 0,
52});
53
54pub static FCC_PACK1_DATA: Mutex<ThreadModeRawMutex, FDCAN_FccPack1_t> =
55 Mutex::new(FDCAN_FccPack1_t {
56 fc_press: 0,
57 fc_temp: 0,
58 });
59pub static FCC_PACK2_DATA: Mutex<ThreadModeRawMutex, FDCAN_FccPack2_t> =
60 Mutex::new(FDCAN_FccPack2_t {
61 fan_rpm1: 0,
62 fan_rpm2: 0,
63 });
64pub static FCC_PACK3_DATA: Mutex<ThreadModeRawMutex, FDCAN_FccPack3_t> =
65 Mutex::new(FDCAN_FccPack3_t {
66 bme_temp: 0,
67 bme_humid: 0,
68 });
69
70pub static H2_PACK1_DATA: Mutex<ThreadModeRawMutex, ECOCAN_H2Pack1_t> =
71 Mutex::new(ECOCAN_H2Pack1_t {
72 h2_sense_1: 0,
73 h2_sense_2: 0,
74 h2_sense_3: 0,
75 h2_sense_4: 0,
76 });
77pub static H2_PACK2_DATA: Mutex<ThreadModeRawMutex, ECOCAN_H2Pack2_t> =
78 Mutex::new(ECOCAN_H2Pack2_t {
79 bme_temp: 0,
80 bme_humid: 0,
81 imon_7v: 0,
82 imon_12v: 0,
83 });
84
85pub static BOOST_PACK1_DATA: Mutex<ThreadModeRawMutex, FDCAN_BOOSTPack1_t> =
86 Mutex::new(FDCAN_BOOSTPack1_t {
87 in_curr: 0,
88 in_volt: 0,
89 });
90pub static BOOST_PACK2_DATA: Mutex<ThreadModeRawMutex, FDCAN_BOOSTPack2_t> =
91 Mutex::new(FDCAN_BOOSTPack2_t {
92 out_curr: 0,
93 out_volt: 0,
94 });
95pub static BOOST_PACK3_DATA: Mutex<ThreadModeRawMutex, FDCAN_BOOSTPack3_t> =
96 Mutex::new(FDCAN_BOOSTPack3_t {
97 efficiency: 0,
98 joules: 0,
99 });
100
101pub static REL_FC_PACK: Mutex<ThreadModeRawMutex, FDCAN_RelPackFc_t> =
103 Mutex::new(FDCAN_RelPackFc_t {
104 fc_volt: 0,
105 fc_curr: 0,
106 });
107pub static REL_CAP_PACK: Mutex<ThreadModeRawMutex, FDCAN_RelPackCap_t> =
108 Mutex::new(FDCAN_RelPackCap_t {
109 cap_volt: 0,
110 cap_curr: 0,
111 });
112pub static RELAY_MOTOR_PACK: Mutex<ThreadModeRawMutex, FDCAN_RelPackMtr_t> =
113 Mutex::new(FDCAN_RelPackMtr_t {
114 mtr_volt: 0,
115 mtr_curr: 0,
116 });
117
118#[embassy_executor::task]
120pub async fn can_receive_task(mut can: Can<'static>) {
121 let debug = true;
124 if debug {
125 let mut tx_data = [0; 64];
126 loop {
127 let mut pack = RELAY_MOTOR_PACK.lock().await;
129 pack.mtr_curr += 1;
130 if pack.mtr_curr > 100 {
131 pack.mtr_curr = 0;
132 }
133 drop(pack);
134
135 match encode_can_package(&RELAY_MOTOR_PACK, &mut tx_data).await {
136 Ok(tx_len) => {
137 let frame =
138 Frame::new_extended(FDCAN_RelPackCap_t::FDCAN_ID, &tx_data[..tx_len])
139 .unwrap();
140 info!("Sending CAN frame...");
141 let _ = can.write(&frame).await;
142 }
144 Err(_) => {
145 error!("CAN Encode Error");
146 }
147 }
148 info!("Sent CAN Frame");
149 Timer::after_millis(1000).await;
150 }
151 }
152 }
168
169async fn _drain_rx_can_buffer(can: &BufferedCanFd<'static, TX_BUF_SIZE, RX_BUF_SIZE>) {
171 let reader = can.reader();
173 for _ in 0..RX_BUF_SIZE {
174 if let Ok(frame) = reader.try_receive() {
175 match frame {
176 Ok(envelope) => {
177 process_rx_can_frame(&envelope.frame).await;
178 }
179 Err(err) => error!("CAN Frame Error: {}", err),
180 }
181 } else {
182 return;
183 }
184 }
185}
186
187async fn process_rx_can_frame(rx_frame: &FdFrame) {
189 if let Err(_) = decode_can_frame(&rx_frame).await {
190 error!("CAN Decode Error");
191 }
192}
193
194async fn decode_can_frame(frame: &FdFrame) -> Result<(), DecodeError> {
198 let id = match frame.header().id() {
200 Id::Standard(id) => u32::from(id.as_raw()),
201 Id::Extended(id) => id.as_raw(),
202 };
203 let rx_data = &frame.data()[..frame.header().len() as usize];
205
206 match id {
208 RelayState::FDCAN_ID => {
209 let mut relay_state = RELAY_STATE.lock().await;
210 *relay_state = RelayState::try_from(rx_data[0])?;
211 debug!("Updated Relay State: {:?}", *relay_state);
212 Ok(())
213 }
214
215 FDCAN_FccPack1_t::FDCAN_ID => decode_can_data(&FCC_PACK1_DATA, rx_data).await,
216 FDCAN_FccPack2_t::FDCAN_ID => decode_can_data(&FCC_PACK2_DATA, rx_data).await,
217 FDCAN_FccPack3_t::FDCAN_ID => decode_can_data(&FCC_PACK3_DATA, rx_data).await,
218
219 FDCAN_FetPack_t::FDCAN_ID => decode_can_data(&FET_DATA, rx_data).await,
220
221 FDCAN_RelPackMtr_t::FDCAN_ID => decode_can_data(&RELAY_MOTOR_PACK, rx_data).await,
222 FDCAN_RelPackCap_t::FDCAN_ID => decode_can_data(&REL_CAP_PACK, rx_data).await,
223 FDCAN_RelPackFc_t::FDCAN_ID => decode_can_data(&REL_FC_PACK, rx_data).await,
224
225 ECOCAN_H2Pack1_t::FDCAN_ID => decode_can_data(&H2_PACK1_DATA, rx_data).await,
226 ECOCAN_H2Pack2_t::FDCAN_ID => decode_can_data(&H2_PACK2_DATA, rx_data).await,
227
228 FDCAN_BOOSTPack1_t::FDCAN_ID => decode_can_data(&BOOST_PACK1_DATA, rx_data).await,
229 FDCAN_BOOSTPack2_t::FDCAN_ID => decode_can_data(&BOOST_PACK2_DATA, rx_data).await,
230 FDCAN_BOOSTPack3_t::FDCAN_ID => decode_can_data(&BOOST_PACK3_DATA, rx_data).await,
231
232 _ => {
233 debug!("Non-Relevant ID: {:016b}", id);
234 Ok(())
235 }
236 }
237}
238
239async fn decode_can_data<T: Decode<()> + Format>(
241 package: &Mutex<ThreadModeRawMutex, T>,
242 rx_data: &[u8],
243) -> Result<(), DecodeError> {
244 let mut p = package.lock().await;
246 *p = bincode::decode_from_slice(&rx_data, BINCODE_CONFIG)?.0;
247 trace!("updated can pack: {:?}", *p);
248
249 Ok(())
250}
251
252async fn encode_can_package<T: Encode + Clone>(
254 package: &Mutex<ThreadModeRawMutex, T>,
255 mut tx_data: &mut [u8],
256) -> Result<usize, EncodeError> {
257 let p = package.lock().await;
258 bincode::encode_into_slice(p.clone(), &mut tx_data, BINCODE_CONFIG)
259}