1use crate::crc;
9use crate::error::Error;
10use crate::registers::Address;
11
12pub const SYNC: u8 = 0x05;
14
15pub const MASTER_ADDR: u8 = 0xFF;
17
18pub const WRITE_BIT: u8 = 0x80;
20
21pub const ADDRESS_MASK: u8 = 0x7F;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub struct ReadRequest {
30 bytes: [u8; Self::LEN],
31}
32
33impl ReadRequest {
34 pub const LEN: usize = 4;
36
37 pub fn new(slave_addr: u8, reg_addr: Address) -> Self {
44 let mut bytes = [SYNC, slave_addr, reg_addr as u8, 0];
45 bytes[3] = crc::compute(&bytes[..3]);
46 Self { bytes }
47 }
48
49 pub fn from_raw_addr(slave_addr: u8, reg_addr: u8) -> Self {
53 let mut bytes = [SYNC, slave_addr, reg_addr & ADDRESS_MASK, 0];
54 bytes[3] = crc::compute(&bytes[..3]);
55 Self { bytes }
56 }
57
58 #[inline]
60 pub fn as_bytes(&self) -> &[u8] {
61 &self.bytes
62 }
63
64 #[inline]
66 pub fn slave_addr(&self) -> u8 {
67 self.bytes[1]
68 }
69
70 #[inline]
72 pub fn reg_addr(&self) -> u8 {
73 self.bytes[2]
74 }
75}
76
77impl AsRef<[u8]> for ReadRequest {
78 fn as_ref(&self) -> &[u8] {
79 &self.bytes
80 }
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88pub struct WriteRequest {
89 bytes: [u8; Self::LEN],
90}
91
92impl WriteRequest {
93 pub const LEN: usize = 8;
95
96 pub fn new(slave_addr: u8, reg_addr: Address, data: u32) -> Self {
104 Self::from_raw(slave_addr, reg_addr as u8, data)
105 }
106
107 pub fn from_raw(slave_addr: u8, reg_addr: u8, data: u32) -> Self {
109 let data_bytes = data.to_be_bytes();
110 let mut bytes = [
111 SYNC,
112 slave_addr,
113 (reg_addr & ADDRESS_MASK) | WRITE_BIT,
114 data_bytes[0],
115 data_bytes[1],
116 data_bytes[2],
117 data_bytes[3],
118 0,
119 ];
120 bytes[7] = crc::compute(&bytes[..7]);
121 Self { bytes }
122 }
123
124 #[inline]
126 pub fn as_bytes(&self) -> &[u8] {
127 &self.bytes
128 }
129
130 #[inline]
132 pub fn slave_addr(&self) -> u8 {
133 self.bytes[1]
134 }
135
136 #[inline]
138 pub fn reg_addr(&self) -> u8 {
139 self.bytes[2] & ADDRESS_MASK
140 }
141
142 #[inline]
144 pub fn data(&self) -> u32 {
145 u32::from_be_bytes([self.bytes[3], self.bytes[4], self.bytes[5], self.bytes[6]])
146 }
147}
148
149impl AsRef<[u8]> for WriteRequest {
150 fn as_ref(&self) -> &[u8] {
151 &self.bytes
152 }
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq)]
159#[cfg_attr(feature = "defmt", derive(defmt::Format))]
160pub struct ReadResponse {
161 bytes: [u8; Self::LEN],
162}
163
164impl ReadResponse {
165 pub const LEN: usize = 8;
167
168 pub const SYNC_IDX: usize = 0;
170 pub const MASTER_ADDR_IDX: usize = 1;
172 pub const REG_ADDR_IDX: usize = 2;
174 pub const DATA_START_IDX: usize = 3;
176 pub const DATA_END_IDX: usize = 7;
178 pub const CRC_IDX: usize = 7;
180
181 pub fn from_bytes<E>(bytes: [u8; Self::LEN]) -> Result<Self, Error<E>> {
191 let response = Self { bytes };
192 response.validate()?;
193 Ok(response)
194 }
195
196 pub fn from_slice<E>(slice: &[u8]) -> Result<Self, Error<E>> {
202 if slice.len() < Self::LEN {
203 return Err(Error::BufferTooSmall);
204 }
205 let mut bytes = [0u8; Self::LEN];
206 bytes.copy_from_slice(&slice[..Self::LEN]);
207 Self::from_bytes(bytes)
208 }
209
210 fn validate<E>(&self) -> Result<(), Error<E>> {
212 if self.bytes[Self::SYNC_IDX] != SYNC {
214 return Err(Error::InvalidSync);
215 }
216
217 if self.bytes[Self::MASTER_ADDR_IDX] != MASTER_ADDR {
219 return Err(Error::InvalidMasterAddress);
220 }
221
222 if !crc::verify(&self.bytes) {
224 return Err(Error::CrcMismatch);
225 }
226
227 Ok(())
228 }
229
230 #[inline]
232 pub fn reg_addr(&self) -> u8 {
233 self.bytes[Self::REG_ADDR_IDX]
234 }
235
236 pub fn address(&self) -> Option<Address> {
238 Address::from_u8(self.reg_addr())
239 }
240
241 #[inline]
243 pub fn data(&self) -> u32 {
244 u32::from_be_bytes([self.bytes[3], self.bytes[4], self.bytes[5], self.bytes[6]])
245 }
246
247 #[inline]
249 pub fn as_bytes(&self) -> &[u8; Self::LEN] {
250 &self.bytes
251 }
252
253 #[inline]
255 pub fn crc_valid(&self) -> bool {
256 crc::verify(&self.bytes)
257 }
258}
259
260impl AsRef<[u8]> for ReadResponse {
261 fn as_ref(&self) -> &[u8] {
262 &self.bytes
263 }
264}
265
266#[derive(Debug, Default)]
271pub struct ResponseReader {
272 index: usize,
274 buffer: [u8; ReadResponse::LEN],
276}
277
278impl ResponseReader {
279 pub fn new() -> Self {
281 Self::default()
282 }
283
284 pub fn reset(&mut self) {
286 self.index = 0;
287 }
288
289 pub fn feed<E>(&mut self, bytes: &[u8]) -> (usize, Option<Result<ReadResponse, Error<E>>>) {
296 let mut consumed = 0;
297 let mut remaining = bytes;
298
299 loop {
300 while self.index == 0 {
302 match remaining.first() {
303 Some(&SYNC) => {
304 self.buffer[0] = SYNC;
305 self.index = 1;
306 remaining = &remaining[1..];
307 consumed += 1;
308 }
309 Some(_) => {
310 remaining = &remaining[1..];
312 consumed += 1;
313 }
314 None => {
315 return (consumed, None);
316 }
317 }
318 }
319
320 if self.index == 1 {
322 match remaining.first() {
323 Some(&MASTER_ADDR) => {
324 self.buffer[1] = MASTER_ADDR;
325 self.index = 2;
326 remaining = &remaining[1..];
327 consumed += 1;
328 }
329 Some(_) => {
330 self.index = 0;
332 continue;
333 }
334 None => {
335 return (consumed, None);
336 }
337 }
338 }
339
340 let needed = ReadResponse::LEN - self.index;
342 let available = remaining.len().min(needed);
343
344 self.buffer[self.index..self.index + available]
345 .copy_from_slice(&remaining[..available]);
346 self.index += available;
347 consumed += available;
348
349 if self.index == ReadResponse::LEN {
351 self.index = 0;
352 let result = ReadResponse::from_bytes(self.buffer);
353 return (consumed, Some(result));
354 }
355
356 return (consumed, None);
357 }
358 }
359
360 pub fn buffered(&self) -> usize {
362 self.index
363 }
364}
365
366#[cfg(test)]
367mod tests {
368 use super::*;
369
370 #[test]
371 fn test_read_request() {
372 let req = ReadRequest::new(0, Address::Gconf);
373 assert_eq!(req.slave_addr(), 0);
374 assert_eq!(req.reg_addr(), 0x00);
375 assert_eq!(req.as_bytes().len(), 4);
376 }
377
378 #[test]
379 fn test_write_request() {
380 let req = WriteRequest::new(0, Address::Gconf, 0x00000040);
381 assert_eq!(req.slave_addr(), 0);
382 assert_eq!(req.reg_addr(), 0x00);
383 assert_eq!(req.data(), 0x00000040);
384 assert_eq!(req.as_bytes().len(), 8);
385 }
386
387 #[test]
388 fn test_response_reader() {
389 let mut response_bytes = [SYNC, MASTER_ADDR, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00];
391 response_bytes[7] = crc::compute(&response_bytes[..7]);
392
393 let mut reader = ResponseReader::new();
394 let (consumed, result) = reader.feed::<()>(&response_bytes);
395
396 assert_eq!(consumed, 8);
397 assert!(result.is_some());
398 let response = result.unwrap().unwrap();
399 assert_eq!(response.data(), 0x00000040);
400 }
401}