pokeys_lib/protocols/
can.rs

1//! CAN protocol implementation
2
3use crate::device::PoKeysDevice;
4use crate::error::Result;
5use crate::types::CanMessage;
6
7/// CAN protocol implementation
8impl PoKeysDevice {
9    /// Configure CAN interface
10    pub fn can_configure(&mut self, baud_rate: u32, mode: u8) -> Result<()> {
11        self.send_request(
12            0xE0,
13            (baud_rate & 0xFF) as u8,
14            ((baud_rate >> 8) & 0xFF) as u8,
15            ((baud_rate >> 16) & 0xFF) as u8,
16            mode,
17        )?;
18        Ok(())
19    }
20
21    /// Send CAN message
22    pub fn can_send(&mut self, message: &CanMessage) -> Result<()> {
23        self.send_request(
24            0xE1,
25            (message.id & 0xFF) as u8,
26            ((message.id >> 8) & 0xFF) as u8,
27            message.len,
28            message.format,
29        )?;
30
31        // Send message data
32        if message.len > 0 {
33            self.send_request(
34                0xE2,
35                message.data[0],
36                message.data[1],
37                message.data[2],
38                message.data[3],
39            )?;
40
41            if message.len > 4 {
42                self.send_request(
43                    0xE3,
44                    message.data[4],
45                    message.data[5],
46                    message.data[6],
47                    message.data[7],
48                )?;
49            }
50        }
51
52        Ok(())
53    }
54
55    /// Receive CAN message
56    pub fn can_receive(&mut self) -> Result<Option<CanMessage>> {
57        let response = self.send_request(0xE4, 0, 0, 0, 0)?;
58
59        if response[8] == 0 {
60            return Ok(None); // No message available
61        }
62
63        let mut message = CanMessage {
64            id: u32::from_le_bytes([response[9], response[10], response[11], response[12]]),
65            data: [0; 8],
66            len: response[13],
67            format: response[14],
68            msg_type: response[15],
69        };
70
71        // Get message data if available
72        if message.len > 0 && response.len() >= 24 {
73            message.data[..message.len as usize]
74                .copy_from_slice(&response[16..16 + message.len as usize]);
75        }
76
77        Ok(Some(message))
78    }
79
80    /// Set CAN filter
81    pub fn can_set_filter(&mut self, filter_id: u32, mask: u32) -> Result<()> {
82        self.send_request(
83            0xE5,
84            (filter_id & 0xFF) as u8,
85            ((filter_id >> 8) & 0xFF) as u8,
86            (mask & 0xFF) as u8,
87            ((mask >> 8) & 0xFF) as u8,
88        )?;
89        Ok(())
90    }
91}