1use crate::status::Status;
4use super::RxBw;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9pub enum ZwaveMode {
10 Lr1 = 0,
11 R1 = 1,
12 R2 = 2,
13 R3 = 3,
14}
15
16impl ZwaveMode {
17 pub fn new(val: u8) -> Self{
18 match val {
19 3 => ZwaveMode::R3,
20 2 => ZwaveMode::R2,
21 _ => ZwaveMode::R1,
22 }
23 }
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub enum ZwaveAddrComp {
30 Off = 0,
31 Homeid = 1,
32 HomeidBeam = 2,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37#[cfg_attr(feature = "defmt", derive(defmt::Format))]
38pub enum FcsMode {
39 Auto = 0,
40 Fifo = 1,
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45#[cfg_attr(feature = "defmt", derive(defmt::Format))]
46pub enum AddrLen {
47 Addr8bit = 0,
48 Addr12bit = 1,
49}
50
51pub fn set_zwave_params_cmd(zwave_mode: ZwaveMode, rx_bw: RxBw, zwave_addr_comp: ZwaveAddrComp, pld_len: u8, pbl_len_tx: u16, pbl_len_detect: u8, fcs_mode: FcsMode) -> [u8; 10] {
53 let mut cmd = [0u8; 10];
54 cmd[0] = 0x02;
55 cmd[1] = 0x97;
56
57 cmd[2] |= (zwave_mode as u8) & 0x3;
58 cmd[3] |= rx_bw as u8;
59 cmd[4] |= zwave_addr_comp as u8;
60 cmd[5] |= pld_len;
61 cmd[6] |= ((pbl_len_tx >> 8) & 0xFF) as u8;
62 cmd[7] |= (pbl_len_tx & 0xFF) as u8;
63 cmd[8] |= pbl_len_detect;
64 cmd[9] |= (fcs_mode as u8) & 0x1;
65 cmd
66}
67
68pub fn set_zwave_home_id_filtering_cmd(home_id: u32) -> [u8; 6] {
70 let mut cmd = [0u8; 6];
71 cmd[0] = 0x02;
72 cmd[1] = 0x98;
73
74 cmd[2] |= ((home_id >> 24) & 0xFF) as u8;
75 cmd[3] |= ((home_id >> 16) & 0xFF) as u8;
76 cmd[4] |= ((home_id >> 8) & 0xFF) as u8;
77 cmd[5] |= (home_id & 0xFF) as u8;
78 cmd
79}
80
81pub fn get_zwave_packet_status_req() -> [u8; 2] {
83 [0x02, 0x9A]
84}
85
86pub fn set_zwave_beam_filtering_cmd(beam_tag: u8, addr_len: AddrLen, node_id: u16, id_hash: u8) -> [u8; 6] {
88 let mut cmd = [0u8; 6];
89 cmd[0] = 0x02;
90 cmd[1] = 0x9B;
91
92 cmd[2] |= beam_tag;
93 cmd[3] |= ((addr_len as u8) & 0x1) << 7;
94 cmd[3] |= ((node_id >> 8) & 0xFF) as u8;
95 cmd[4] |= (node_id & 0xFF) as u8;
96 cmd[5] |= id_hash;
97 cmd
98}
99
100pub fn set_zwave_scan_cmd() -> [u8; 2] {
102 [0x02, 0x9D]
103}
104
105pub fn get_zwave_rx_stats_req() -> [u8; 2] {
107 [0x02, 0x99]
108}
109
110#[derive(Default)]
114pub struct ZwavePacketStatusRsp([u8; 9]);
115
116impl ZwavePacketStatusRsp {
117 pub fn new() -> Self {
119 Self::default()
120 }
121
122 pub fn status(&mut self) -> Status {
124 Status::from_slice(&self.0[..2])
125 }
126
127 pub fn pkt_len(&self) -> u16 {
129 (self.0[3] as u16) |
130 ((self.0[2] as u16) << 8)
131 }
132
133 pub fn rssi_avg(&self) -> u16 {
135 (((self.0[7] >> 2) & 0x1) as u16) |
136 ((self.0[4] as u16) << 1)
137 }
138
139 pub fn rssi_sync(&self) -> u16 {
141 ((self.0[7] & 0x1) as u16) |
142 ((self.0[5] as u16) << 1)
143 }
144
145 pub fn last_detect(&self) -> ZwaveMode {
147 ZwaveMode::new(self.0[6] & 0x3)
148 }
149
150 pub fn lqi(&self) -> u8 {
152 self.0[8]
153 }
154}
155
156impl AsMut<[u8]> for ZwavePacketStatusRsp {
157 fn as_mut(&mut self) -> &mut [u8] {
158 &mut self.0
159 }
160}
161
162#[derive(Default)]
164pub struct ZwaveRxStatsRsp([u8; 8]);
165
166impl ZwaveRxStatsRsp {
167 pub fn new() -> Self {
169 Self::default()
170 }
171
172 pub fn status(&mut self) -> Status {
174 Status::from_slice(&self.0[..2])
175 }
176
177 pub fn pkt_rx(&self) -> u16 {
179 (self.0[3] as u16) |
180 ((self.0[2] as u16) << 8)
181 }
182
183 pub fn crc_error(&self) -> u16 {
185 (self.0[5] as u16) |
186 ((self.0[4] as u16) << 8)
187 }
188
189 pub fn len_error(&self) -> u16 {
191 (self.0[7] as u16) |
192 ((self.0[6] as u16) << 8)
193 }
194}
195
196impl AsMut<[u8]> for ZwaveRxStatsRsp {
197 fn as_mut(&mut self) -> &mut [u8] {
198 &mut self.0
199 }
200}