Dashboard/
eco_can.rs

1#![no_std]
2//! Module for CAN communication
3//! ### CAN Package Information
4//! A CAN package is setup like this:
5//! ```rust
6//! #[allow(non_camel_case_types)]
7//! #[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
8//! #[repr(C)]
9//! pub struct FDCAN_PACKAGE_NAME {
10//!     // Package Data
11//! }
12//! impl FDCANPack for FDCAN_FetPack_t {
13//!    const FDCAN_BYTES: u8 = BYTE_LENGTH; // set this to the size of the package in bytes
14//!    const FDCAN_ID: u16 = CAN_ID;    // the ID of the CAN package
15//! }
16//! ```
17//! `#[allow(non_camel_case_types)]` allows non-camel-case names for FDCAN packages
18//!
19//! `#[derive(bincode::Encode, bincode::Decode)]` makes the
20//! package able to be encoded to and decoded from bytes.
21//!
22//! `#[derive(Clone)]` allows the package to be copied.
23//!
24//! `#[derive(Debug)]` allows the package to be formatted in log messages.
25//!
26//! `#[repr(C)]` Make Rust use the same memory layout for this struct as C to ensure compatility.
27//! For more information: [https://doc.rust-lang.org/nomicon/other-reprs.html](https://doc.rust-lang.org/nomicon/other-reprs.html)
28
29/// The length of the package in bytes, can be up to 64 bytes.
30///
31/// pub structs must be a certain size for FDCAN to transfer
32/// The following package sizes (in bytes) are 0, 1, 2, 3, 4, 5, 6,
33/// 7, 8, 12, 16, 20, 24, 32, 48, 64.
34#[allow(non_camel_case_types)]
35pub enum FDCANLength {
36    BYTES_0 = 0,
37    BYTES_1 = 1,
38    BYTES_2 = 2,
39    BYTES_3 = 3,
40    BYTES_4 = 4,
41    BYTES_5 = 5,
42    BYTES_6 = 6,
43    BYTES_7 = 7,
44    BYTES_8 = 8,
45    BYTES_12 = 12,
46    BYTES_16 = 16,
47    BYTES_20 = 20,
48    BYTES_24 = 24,
49    BYTES_32 = 32,
50    BYTES_48 = 48,
51    BYTES_64 = 64,
52}
53
54/// Prerequisite trait for FDCAN Packages
55///
56/// Sets the ID and number of bytes for a CAN package.
57/// Note that associated constants do not increase the size of a struct's memory.
58pub trait FDCANPack: bincode::enc::Encode + Clone {
59    /// The length of the package in bytes, can be up to 64 bytes.
60    ///
61    /// pub structs must be a certain size for FDCAN to transfer
62    /// The following package sizes (in bytes) are 0, 1, 2, 3, 4, 5, 6,
63    /// 7, 8, 12, 16, 20, 24, 32, 48, 64.
64    const FDCAN_BYTES: FDCANLength;
65    /// 12 bit ID
66    ///
67    /// Reserved IDs up to 0x01F
68    ///
69    /// 0x010 = 0b00000010000
70    ///
71    /// 0x01F = 0b00000011111
72    ///
73    /// To receive all can filter ids within
74    /// this range you must set the mask to
75    /// 0x7F0 = 0b11111110000
76    ///
77    /// because you care that the bits \[10:4\]
78    /// of the can id are exactly the same as
79    /// bits \[10:4\] in 0x010/0x01F but the last four bits \[3:0\] can be 0 or 1
80    /// The same logic will be applied henceforth
81    const FDCAN_ID: u16;
82}
83
84// Highest priority CAN messages
85// ranging from 0x000 to 0x00F
86// All boards must accept these
87// messages
88/// 1 indicates tripped alarm
89pub const FDCAN_H2ALARM_ID: u16 = 0x001;
90/// 1 indicates led on
91pub const FDCAN_SYNCLED_ID: u16 = 0x00F;
92/// Relay State ID
93pub const FDCAN_RELSTATE_ID: u16 = 0x018;
94
95#[allow(non_camel_case_types)]
96#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
97#[repr(C)]
98pub struct FDCAN_FetPack_t {
99    pub fet_config: u32,
100    pub input_volt: u32,
101    pub cap_volt: u32,
102    pub cap_curr: u32,
103    pub res_curr: u32,
104    pub out_curr: u32,
105}
106impl FDCANPack for FDCAN_FetPack_t {
107    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_24;
108    const FDCAN_ID: u16 = 0x010;
109}
110
111#[allow(non_camel_case_types)]
112#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
113#[repr(C)]
114pub struct ECOCAN_RelPackChrg_t {
115    fc_coloumbs: i32,
116    cap_coloumbs: i32,
117}
118impl FDCANPack for ECOCAN_RelPackChrg_t {
119    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
120    const FDCAN_ID: u16 = 0x013;
121}
122
123#[allow(non_camel_case_types)]
124#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
125#[repr(C)]
126pub struct FDCAN_RelPackNrg_t {
127    pub fc_joules: i32,
128    pub cap_joules: i32,
129}
130impl FDCANPack for FDCAN_RelPackNrg_t {
131    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
132    const FDCAN_ID: u16 = 0x014;
133}
134
135#[allow(non_camel_case_types)]
136#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
137#[repr(C)]
138pub struct FDCAN_RelPackMtr_t {
139    pub mtr_volt: u32,
140    pub mtr_curr: u32,
141}
142impl FDCANPack for FDCAN_RelPackMtr_t {
143    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
144    const FDCAN_ID: u16 = 0x015;
145}
146
147#[allow(non_camel_case_types)]
148#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
149#[repr(C)]
150pub struct FDCAN_RelPackCap_t {
151    pub cap_volt: u32,
152    pub cap_curr: i32,
153}
154impl FDCANPack for FDCAN_RelPackCap_t {
155    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
156    const FDCAN_ID: u16 = 0x016;
157}
158
159#[allow(non_camel_case_types)]
160#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
161#[repr(C)]
162pub struct FDCAN_RelPackFc_t {
163    pub fc_volt: u32,
164    pub fc_curr: u32,
165}
166impl FDCANPack for FDCAN_RelPackFc_t {
167    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
168    const FDCAN_ID: u16 = 0x017;
169}
170
171#[allow(non_camel_case_types)]
172#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
173#[repr(C)]
174pub struct FDCAN_FccPack1_t {
175    pub fc_temp: i32,
176    pub fc_press: u32,
177}
178impl FDCANPack for FDCAN_FccPack1_t {
179    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
180    const FDCAN_ID: u16 = 0x020;
181}
182
183#[allow(non_camel_case_types)]
184#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
185#[repr(C)]
186pub struct FDCAN_FccPack2_t {
187    pub fan_rpm1: u32,
188    pub fan_rpm2: u32,
189}
190impl FDCANPack for FDCAN_FccPack2_t {
191    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
192    const FDCAN_ID: u16 = 0x021;
193}
194
195#[allow(non_camel_case_types)]
196#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
197#[repr(C)]
198pub struct FDCAN_FccPack3_t {
199    pub bme_temp: u32,
200    pub bme_humid: u32,
201}
202impl FDCANPack for FDCAN_FccPack3_t {
203    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
204    const FDCAN_ID: u16 = 0x022;
205}
206
207// Reserved IDs up to 0x03F
208// 0x030 = 0b00001000000
209// 0x03F = 0b00001001111
210// Mask: 0x7F0
211
212#[allow(non_camel_case_types)]
213#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
214#[repr(C)]
215pub struct ECOCAN_H2Pack1_t {
216    pub h2_sense_1: u16,
217    pub h2_sense_2: u16,
218    pub h2_sense_3: u16,
219    pub h2_sense_4: u16,
220}
221impl FDCANPack for ECOCAN_H2Pack1_t {
222    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
223    const FDCAN_ID: u16 = 0x030;
224}
225
226#[allow(non_camel_case_types)]
227#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
228#[repr(C)]
229pub struct ECOCAN_H2Pack2_t {
230    pub bme_temp: u16,
231    pub bme_humid: u16,
232    pub imon_7v: u16,
233    pub imon_12v: u16,
234}
235impl FDCANPack for ECOCAN_H2Pack2_t {
236    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
237    const FDCAN_ID: u16 = 0x031;
238}
239
240#[allow(non_camel_case_types)]
241#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
242#[repr(C)]
243pub struct ECOCAN_H2_ARM_ALARM_t {
244    pub h2_alarm_armed: u8,
245}
246impl FDCANPack for ECOCAN_H2_ARM_ALARM_t {
247    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_1;
248    const FDCAN_ID: u16 = 0x032;
249}
250
251#[allow(non_camel_case_types)]
252#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
253#[repr(C)]
254pub struct FDCAN_BOOSTPack_t {
255    pub in_curr: u32,
256    pub in_volt: u32,
257}
258impl FDCANPack for FDCAN_BOOSTPack_t {
259    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
260    const FDCAN_ID: u16 = 0x040;
261}
262
263#[allow(non_camel_case_types)]
264#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
265#[repr(C)]
266pub struct FDCAN_BOOSTPack2_t {
267    pub out_curr: u32,
268    pub out_volt: u32,
269}
270impl FDCANPack for FDCAN_BOOSTPack2_t {
271    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
272    const FDCAN_ID: u16 = 0x041;
273}
274
275#[allow(non_camel_case_types)]
276#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
277#[repr(C)]
278pub struct FDCAN_BOOSTPack3_t {
279    pub efficiency: u32,
280    pub joules: u32,
281}
282impl FDCANPack for FDCAN_BOOSTPack3_t {
283    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_8;
284    const FDCAN_ID: u16 = 0x042;
285}
286
287#[allow(non_camel_case_types)]
288#[derive(bincode::Encode, bincode::Decode, PartialEq, Clone, Debug)]
289#[repr(C)]
290pub struct FDCAN_BATTPack2_t {
291    pub out_curr: u16,
292    pub out_volt: u16,
293}
294impl FDCANPack for FDCAN_BATTPack2_t {
295    const FDCAN_BYTES: FDCANLength = FDCANLength::BYTES_4;
296    const FDCAN_ID: u16 = 0x050;
297}