umsh_ulcp/
i2c.rs

1//! Raw I2C bus access: `CMD_I2C_TRANSFER`, `CMD_I2C_SCAN`, their common
2//! reply `CMD_I2C_RESULT`, and the two tables that describe what a host
3//! may address (`PROP_I2C_BUSES`, `PROP_I2C_DEVICES`).
4//!
5//! A transfer is one bus transaction with the semantics of embedded-hal
6//! 1.0's `I2c::transaction`: a START, the address, the operations in
7//! order with a repeated START on each change of direction and no
8//! restart between consecutive operations of the same direction, and one
9//! STOP at the end. The wire form is
10//!
11//! ```text
12//! BUS (UINT8) | ADDR (UINT8) | OP | OP | ...
13//! OP = KIND (UINT8: 0 write, 1 read) | LEN (PUI) | [LEN data octets, write only]
14//! ```
15//!
16//! This module validates structure and the protocol's own rules (a
17//! 7-bit address, a known kind, no empty operations, at least one
18//! operation). The per-bus limits a device advertises—how much data and
19//! how many operations one transfer may carry—are the device's to
20//! enforce, since only it knows which bus is meant.
21
22use crate::frame::{Cmd, FrameWriter, WriteError};
23use crate::items::{self, ItemError};
24use crate::pui;
25use crate::status::Status;
26
27/// Largest 7-bit address.
28pub const ADDRESS_MAX: u8 = 0x7F;
29/// First address a scan probes when the request names no range: the
30/// addresses below are reserved (general call, START byte, CBUS, and the
31/// high-speed master codes).
32pub const SCAN_DEFAULT_FIRST: u8 = 0x08;
33/// Last address a scan probes when the request names no range: the
34/// addresses above are reserved for 10-bit addressing and future use.
35pub const SCAN_DEFAULT_LAST: u8 = 0x77;
36
37/// Why a request could not be honored, before any bus was touched.
38#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub enum I2cError {
40    /// The payload is truncated or its structure cannot be parsed.
41    Parse,
42    /// The structure parses but a value breaks the protocol's rules: an
43    /// address above 7 bits, an unknown operation kind, an empty
44    /// operation, no operations at all, or a scan range that is not
45    /// ascending or reaches past 0x7F.
46    Invalid,
47}
48
49impl I2cError {
50    /// The status a device answers with.
51    pub const fn status(self) -> Status {
52        match self {
53            Self::Parse => Status::PARSE_ERROR,
54            Self::Invalid => Status::INVALID_ARGUMENT,
55        }
56    }
57}
58
59/// The direction of one operation.
60#[derive(Clone, Copy, Debug, PartialEq, Eq)]
61#[repr(u8)]
62pub enum OpKind {
63    Write = 0,
64    Read = 1,
65}
66
67impl OpKind {
68    pub const fn code(self) -> u8 {
69        self as u8
70    }
71
72    pub const fn from_code(code: u8) -> Option<Self> {
73        match code {
74            0 => Some(Self::Write),
75            1 => Some(Self::Read),
76            _ => None,
77        }
78    }
79}
80
81/// One operation of a transfer.
82#[derive(Clone, Copy, Debug, PartialEq, Eq)]
83pub enum Op<'a> {
84    /// Write these octets.
85    Write(&'a [u8]),
86    /// Read this many octets.
87    Read(usize),
88}
89
90impl Op<'_> {
91    pub const fn kind(&self) -> OpKind {
92        match self {
93            Self::Write(_) => OpKind::Write,
94            Self::Read(_) => OpKind::Read,
95        }
96    }
97
98    /// The octets this operation moves, in either direction.
99    pub const fn data_len(&self) -> usize {
100        match self {
101            Self::Write(data) => data.len(),
102            Self::Read(len) => *len,
103        }
104    }
105
106    /// Space the operation occupies on the wire.
107    pub const fn wire_len(&self) -> usize {
108        let len = self.data_len();
109        let body = match self {
110            Self::Write(_) => len,
111            Self::Read(_) => 0,
112        };
113        1 + pui::encoded_len(len as u32) + body
114    }
115
116    fn write(&self, writer: &mut FrameWriter<'_>) -> Result<(), WriteError> {
117        writer.write_u8(self.kind().code())?;
118        let len = u32::try_from(self.data_len()).map_err(|_| WriteError::ValueTooLarge)?;
119        writer.write_pui(len)?;
120        if let Self::Write(data) = self {
121            writer.write_bytes(data)?;
122        }
123        Ok(())
124    }
125}
126
127/// The operations of a transfer, decoded one at a time from their wire
128/// form. Yields an error and then ends when the list is malformed, so a
129/// device validates the whole list before touching the bus.
130#[derive(Clone)]
131pub struct Ops<'a> {
132    rest: &'a [u8],
133}
134
135impl<'a> Iterator for Ops<'a> {
136    type Item = Result<Op<'a>, I2cError>;
137
138    fn next(&mut self) -> Option<Self::Item> {
139        let [kind, rest @ ..] = self.rest else {
140            return None;
141        };
142        let result = (|| {
143            let kind = OpKind::from_code(*kind).ok_or(I2cError::Invalid)?;
144            let (len, consumed) = pui::decode(rest).map_err(|_| I2cError::Parse)?;
145            let len = usize::try_from(len).map_err(|_| I2cError::Parse)?;
146            if len == 0 {
147                return Err(I2cError::Invalid);
148            }
149            let rest = &rest[consumed..];
150            match kind {
151                OpKind::Read => Ok((Op::Read(len), rest)),
152                OpKind::Write => {
153                    if rest.len() < len {
154                        return Err(I2cError::Parse);
155                    }
156                    let (data, rest) = rest.split_at(len);
157                    Ok((Op::Write(data), rest))
158                }
159            }
160        })();
161        match result {
162            Ok((op, rest)) => {
163                self.rest = rest;
164                Some(Ok(op))
165            }
166            Err(error) => {
167                self.rest = &[];
168                Some(Err(error))
169            }
170        }
171    }
172}
173
174/// What a transfer amounts to, summed over its operations.
175#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
176pub struct TransferShape {
177    /// Operations in the list.
178    pub ops: usize,
179    /// Octets written and read together, which the device's `MAX_DATA`
180    /// limit bounds.
181    pub data_len: usize,
182    /// Octets the reply will carry.
183    pub read_len: usize,
184}
185
186/// A `CMD_I2C_TRANSFER` request whose structure has been validated.
187#[derive(Clone, Copy, Debug, PartialEq, Eq)]
188pub struct TransferRequest<'a> {
189    pub bus: u8,
190    /// The 7-bit address.
191    pub addr: u8,
192    ops: &'a [u8],
193}
194
195impl<'a> TransferRequest<'a> {
196    /// Decode and validate a `CMD_I2C_TRANSFER` payload.
197    pub fn parse(payload: &'a [u8]) -> Result<Self, I2cError> {
198        let [bus, addr, ops @ ..] = payload else {
199            return Err(I2cError::Parse);
200        };
201        if *addr > ADDRESS_MAX {
202            return Err(I2cError::Invalid);
203        }
204        let request = Self {
205            bus: *bus,
206            addr: *addr,
207            ops,
208        };
209        let mut count = 0usize;
210        for op in request.ops() {
211            op?;
212            count += 1;
213        }
214        if count == 0 {
215            return Err(I2cError::Invalid);
216        }
217        Ok(request)
218    }
219
220    /// Reassemble a request from its parts, for a device that staged the
221    /// operation list of a request it already validated.
222    pub const fn from_parts(bus: u8, addr: u8, ops: &'a [u8]) -> Self {
223        Self { bus, addr, ops }
224    }
225
226    /// The operation list in wire form.
227    pub const fn encoded_ops(&self) -> &'a [u8] {
228        self.ops
229    }
230
231    /// The operations, in order.
232    pub const fn ops(&self) -> Ops<'a> {
233        Ops { rest: self.ops }
234    }
235
236    /// Sum the list up. Malformed operations are skipped, so call this
237    /// on a request that [`Self::parse`] accepted.
238    pub fn shape(&self) -> TransferShape {
239        let mut shape = TransferShape::default();
240        for op in self.ops().flatten() {
241            shape.ops += 1;
242            shape.data_len += op.data_len();
243            if let Op::Read(len) = op {
244                shape.read_len += len;
245            }
246        }
247        shape
248    }
249}
250
251/// Encode a `CMD_I2C_TRANSFER` frame.
252pub fn encode_transfer(
253    buf: &mut [u8],
254    tid: u8,
255    bus: u8,
256    addr: u8,
257    ops: &[Op<'_>],
258) -> Result<usize, WriteError> {
259    let mut writer = FrameWriter::new(buf, tid, Cmd::I2cTransfer)?;
260    writer.write_u8(bus)?;
261    writer.write_u8(addr)?;
262    for op in ops {
263        op.write(&mut writer)?;
264    }
265    Ok(writer.finish())
266}
267
268/// A `CMD_I2C_SCAN` request with an absent range resolved to the
269/// default.
270#[derive(Clone, Copy, Debug, PartialEq, Eq)]
271pub struct ScanRequest {
272    pub bus: u8,
273    pub first: u8,
274    pub last: u8,
275}
276
277impl ScanRequest {
278    /// A scan of the default range.
279    pub const fn new(bus: u8) -> Self {
280        Self {
281            bus,
282            first: SCAN_DEFAULT_FIRST,
283            last: SCAN_DEFAULT_LAST,
284        }
285    }
286
287    /// Decode and validate a `CMD_I2C_SCAN` payload.
288    pub fn parse(payload: &[u8]) -> Result<Self, I2cError> {
289        let request = match payload {
290            &[bus] => Self::new(bus),
291            &[bus, first, last] => Self { bus, first, last },
292            _ => return Err(I2cError::Parse),
293        };
294        if request.first > request.last || request.last > ADDRESS_MAX {
295            return Err(I2cError::Invalid);
296        }
297        Ok(request)
298    }
299
300    /// How many addresses the scan probes, which bounds the reply.
301    pub const fn len(&self) -> usize {
302        self.last as usize - self.first as usize + 1
303    }
304
305    /// Whether `addr` is among the addresses probed.
306    pub const fn covers(&self, addr: u8) -> bool {
307        self.first <= addr && addr <= self.last
308    }
309}
310
311/// Encode a `CMD_I2C_SCAN` frame; `range` is `None` for the default.
312pub fn encode_scan(
313    buf: &mut [u8],
314    tid: u8,
315    bus: u8,
316    range: Option<(u8, u8)>,
317) -> Result<usize, WriteError> {
318    let mut writer = FrameWriter::new(buf, tid, Cmd::I2cScan)?;
319    writer.write_u8(bus)?;
320    if let Some((first, last)) = range {
321        writer.write_u8(first)?;
322        writer.write_u8(last)?;
323    }
324    Ok(writer.finish())
325}
326
327/// Encode a `CMD_I2C_RESULT` frame carrying `data`: the octets a
328/// transfer read, or the addresses a scan found.
329pub fn encode_result(buf: &mut [u8], tid: u8, data: &[u8]) -> Result<usize, WriteError> {
330    let mut writer = FrameWriter::new(buf, tid, Cmd::I2cResult)?;
331    writer.write_bytes(data)?;
332    Ok(writer.finish())
333}
334
335/// Octets a `CMD_I2C_RESULT` frame occupies beyond its payload: the
336/// header and the command identifier.
337pub const RESULT_OVERHEAD: usize = 2;
338
339/// One `PROP_I2C_BUSES` item.
340///
341/// ```text
342/// BUS (UINT8) | SPEED_KHZ (UINT16) | MAX_DATA (UINT16) | MAX_OPS (UINT8) | NAME (UTF-8)
343/// ```
344#[derive(Clone, Copy, Debug, PartialEq, Eq)]
345pub struct BusInfo<'a> {
346    pub bus: u8,
347    /// The clock the device drives the bus at.
348    pub speed_khz: u16,
349    /// The largest sum of write-data and read-length octets one
350    /// transfer may carry.
351    pub max_data: u16,
352    /// The largest operation count one transfer may carry.
353    pub max_ops: u8,
354    /// Display text for the bus: its controller and pins, typically.
355    pub name: &'a str,
356}
357
358impl<'a> BusInfo<'a> {
359    const FIXED_LEN: usize = 6;
360
361    /// Space the item occupies without its length prefix.
362    pub const fn wire_len(&self) -> usize {
363        Self::FIXED_LEN + self.name.len()
364    }
365
366    /// Append the item with its length prefix, returning the octets
367    /// written.
368    pub fn encode(&self, out: &mut [u8]) -> Result<usize, ItemError> {
369        let mut item = [0u8; Self::FIXED_LEN + NAME_MAX_LEN];
370        let len = self.wire_len();
371        if len > item.len() {
372            return Err(ItemError::BadLength);
373        }
374        item[0] = self.bus;
375        item[1..3].copy_from_slice(&self.speed_khz.to_le_bytes());
376        item[3..5].copy_from_slice(&self.max_data.to_le_bytes());
377        item[5] = self.max_ops;
378        item[6..len].copy_from_slice(self.name.as_bytes());
379        items::encode_prefixed_item(&item[..len], out)
380    }
381
382    /// Decode one item (without its length prefix).
383    pub fn decode(item: &'a [u8]) -> Result<Self, I2cError> {
384        let [
385            bus,
386            speed_lo,
387            speed_hi,
388            max_data_lo,
389            max_data_hi,
390            max_ops,
391            name @ ..,
392        ] = item
393        else {
394            return Err(I2cError::Parse);
395        };
396        let name = core::str::from_utf8(name).map_err(|_| I2cError::Invalid)?;
397        Ok(Self {
398            bus: *bus,
399            speed_khz: u16::from_le_bytes([*speed_lo, *speed_hi]),
400            max_data: u16::from_le_bytes([*max_data_lo, *max_data_hi]),
401            max_ops: *max_ops,
402            name,
403        })
404    }
405}
406
407/// Longest bus or device name this crate encodes.
408pub const NAME_MAX_LEN: usize = 64;
409
410/// One `PROP_I2C_DEVICES` item.
411///
412/// ```text
413/// BUS (UINT8) | ADDR (UINT8) | NAME (UTF-8)
414/// ```
415#[derive(Clone, Copy, Debug, PartialEq, Eq)]
416pub struct DeviceInfo<'a> {
417    pub bus: u8,
418    /// The 7-bit address.
419    pub addr: u8,
420    /// The part the firmware knows to be there.
421    pub name: &'a str,
422}
423
424impl<'a> DeviceInfo<'a> {
425    const FIXED_LEN: usize = 2;
426
427    /// Space the item occupies without its length prefix.
428    pub const fn wire_len(&self) -> usize {
429        Self::FIXED_LEN + self.name.len()
430    }
431
432    /// Append the item with its length prefix, returning the octets
433    /// written.
434    pub fn encode(&self, out: &mut [u8]) -> Result<usize, ItemError> {
435        let mut item = [0u8; Self::FIXED_LEN + NAME_MAX_LEN];
436        let len = self.wire_len();
437        if len > item.len() {
438            return Err(ItemError::BadLength);
439        }
440        item[0] = self.bus;
441        item[1] = self.addr;
442        item[2..len].copy_from_slice(self.name.as_bytes());
443        items::encode_prefixed_item(&item[..len], out)
444    }
445
446    /// Decode one item (without its length prefix).
447    pub fn decode(item: &'a [u8]) -> Result<Self, I2cError> {
448        let [bus, addr, name @ ..] = item else {
449            return Err(I2cError::Parse);
450        };
451        let name = core::str::from_utf8(name).map_err(|_| I2cError::Invalid)?;
452        Ok(Self {
453            bus: *bus,
454            addr: *addr,
455            name,
456        })
457    }
458}
459
460/// Decode a whole `PROP_I2C_BUSES` value.
461pub fn buses(value: &[u8]) -> impl Iterator<Item = Result<BusInfo<'_>, I2cError>> {
462    items::prefixed_items(value).map(|item| BusInfo::decode(item.map_err(|_| I2cError::Parse)?))
463}
464
465/// Decode a whole `PROP_I2C_DEVICES` value.
466pub fn devices(value: &[u8]) -> impl Iterator<Item = Result<DeviceInfo<'_>, I2cError>> {
467    items::prefixed_items(value).map(|item| DeviceInfo::decode(item.map_err(|_| I2cError::Parse)?))
468}
469
470#[cfg(test)]
471mod tests {
472    use super::*;
473    use crate::frame::Frame;
474
475    fn payload(buf: &[u8], cmd: Cmd, tid: u8) -> &[u8] {
476        let frame = Frame::parse(buf).unwrap();
477        assert_eq!(frame.command(), Some(cmd));
478        assert_eq!(frame.header.tid(), tid);
479        frame.payload
480    }
481
482    #[test]
483    fn a_register_read_round_trips() {
484        let mut buf = [0u8; 32];
485        let ops = [Op::Write(&[0x08]), Op::Read(2)];
486        let len = encode_transfer(&mut buf, 3, 0, 0x55, &ops).unwrap();
487        assert_eq!(buf[1], Cmd::I2cTransfer as u8);
488        assert_eq!(&buf[2..len], &[0, 0x55, 0, 1, 0x08, 1, 2]);
489        let request = TransferRequest::parse(payload(&buf[..len], Cmd::I2cTransfer, 3)).unwrap();
490        assert_eq!((request.bus, request.addr), (0, 0x55));
491        let decoded: Vec<Op<'_>> = request.ops().collect::<Result<_, _>>().unwrap();
492        assert_eq!(decoded, ops);
493        assert_eq!(
494            request.shape(),
495            TransferShape {
496                ops: 2,
497                data_len: 3,
498                read_len: 2,
499            }
500        );
501        // Reassembled from staged parts, the request reads the same.
502        let staged = TransferRequest::from_parts(0, 0x55, request.encoded_ops());
503        assert_eq!(staged, request);
504    }
505
506    #[test]
507    fn long_operations_take_a_two_octet_length() {
508        let data = [0xA5u8; 200];
509        let ops = [Op::Write(&data), Op::Read(150)];
510        assert_eq!(ops[0].wire_len(), 1 + 2 + 200);
511        assert_eq!(ops[1].wire_len(), 1 + 2);
512        let mut buf = [0u8; 256];
513        let len = encode_transfer(&mut buf, 0, 1, 0x50, &ops).unwrap();
514        assert_eq!(len, 2 + 2 + ops[0].wire_len() + ops[1].wire_len());
515        let request = TransferRequest::parse(payload(&buf[..len], Cmd::I2cTransfer, 0)).unwrap();
516        let decoded: Vec<Op<'_>> = request.ops().collect::<Result<_, _>>().unwrap();
517        assert_eq!(decoded, ops);
518        assert_eq!(request.shape().data_len, 350);
519        assert_eq!(request.shape().read_len, 150);
520    }
521
522    #[test]
523    fn invalid_transfers_are_refused_before_the_bus() {
524        // Address above 7 bits.
525        assert_eq!(
526            TransferRequest::parse(&[0, 0x80, 1, 1]),
527            Err(I2cError::Invalid)
528        );
529        // Unknown operation kind.
530        assert_eq!(
531            TransferRequest::parse(&[0, 0x50, 2, 1]),
532            Err(I2cError::Invalid)
533        );
534        // An empty operation.
535        assert_eq!(
536            TransferRequest::parse(&[0, 0x50, 1, 0]),
537            Err(I2cError::Invalid)
538        );
539        assert_eq!(
540            TransferRequest::parse(&[0, 0x50, 0, 0]),
541            Err(I2cError::Invalid)
542        );
543        // No operations at all.
544        assert_eq!(TransferRequest::parse(&[0, 0x50]), Err(I2cError::Invalid));
545        // A valid operation followed by an invalid one still fails.
546        assert_eq!(
547            TransferRequest::parse(&[0, 0x50, 1, 1, 7, 1]),
548            Err(I2cError::Invalid)
549        );
550    }
551
552    #[test]
553    fn truncated_transfers_are_parse_errors() {
554        assert_eq!(TransferRequest::parse(&[]), Err(I2cError::Parse));
555        assert_eq!(TransferRequest::parse(&[0]), Err(I2cError::Parse));
556        // A kind with no length.
557        assert_eq!(TransferRequest::parse(&[0, 0x50, 1]), Err(I2cError::Parse));
558        // Write data shorter than its length.
559        assert_eq!(
560            TransferRequest::parse(&[0, 0x50, 0, 3, 0xAA]),
561            Err(I2cError::Parse)
562        );
563        // A length whose PUI never ends.
564        assert_eq!(
565            TransferRequest::parse(&[0, 0x50, 1, 0x80]),
566            Err(I2cError::Parse)
567        );
568        assert_eq!(I2cError::Parse.status(), Status::PARSE_ERROR);
569        assert_eq!(I2cError::Invalid.status(), Status::INVALID_ARGUMENT);
570    }
571
572    #[test]
573    fn scan_requests_default_and_validate_their_range() {
574        let mut buf = [0u8; 8];
575        let len = encode_scan(&mut buf, 5, 2, None).unwrap();
576        assert_eq!(len, 3);
577        let request = ScanRequest::parse(payload(&buf[..len], Cmd::I2cScan, 5)).unwrap();
578        assert_eq!(request, ScanRequest::new(2));
579        assert_eq!(request.len(), 0x70);
580        assert!(request.covers(0x08));
581        assert!(request.covers(0x77));
582        assert!(!request.covers(0x78));
583
584        let len = encode_scan(&mut buf, 5, 0, Some((0x50, 0x57))).unwrap();
585        let request = ScanRequest::parse(payload(&buf[..len], Cmd::I2cScan, 5)).unwrap();
586        assert_eq!(
587            request,
588            ScanRequest {
589                bus: 0,
590                first: 0x50,
591                last: 0x57,
592            }
593        );
594        assert_eq!(request.len(), 8);
595
596        assert_eq!(ScanRequest::parse(&[]), Err(I2cError::Parse));
597        assert_eq!(ScanRequest::parse(&[0, 0x10]), Err(I2cError::Parse));
598        assert_eq!(
599            ScanRequest::parse(&[0, 0x10, 0x20, 0]),
600            Err(I2cError::Parse)
601        );
602        assert_eq!(ScanRequest::parse(&[0, 0x20, 0x10]), Err(I2cError::Invalid));
603        assert_eq!(ScanRequest::parse(&[0, 0x10, 0x80]), Err(I2cError::Invalid));
604        // A single address is a valid range.
605        assert!(ScanRequest::parse(&[0, 0x55, 0x55]).is_ok());
606    }
607
608    #[test]
609    fn results_carry_their_data_verbatim() {
610        let mut buf = [0u8; 16];
611        let len = encode_result(&mut buf, 6, &[0x20, 0x28, 0x34]).unwrap();
612        assert_eq!(len, RESULT_OVERHEAD + 3);
613        assert_eq!(payload(&buf[..len], Cmd::I2cResult, 6), &[0x20, 0x28, 0x34]);
614        let len = encode_result(&mut buf, 6, &[]).unwrap();
615        assert_eq!(payload(&buf[..len], Cmd::I2cResult, 6), &[]);
616    }
617
618    #[test]
619    fn bus_and_device_tables_round_trip() {
620        let bus = BusInfo {
621            bus: 0,
622            speed_khz: 400,
623            max_data: 255,
624            max_ops: 16,
625            name: "I2C0 SDA GPIO3 SCL GPIO2",
626        };
627        let mut table = [0u8; 64];
628        let len = bus.encode(&mut table).unwrap();
629        assert_eq!(len, 1 + bus.wire_len());
630        assert_eq!(&table[1..7], &[0, 0x90, 0x01, 0xFF, 0x00, 16]);
631        let decoded: Vec<BusInfo<'_>> = buses(&table[..len]).collect::<Result<_, _>>().unwrap();
632        assert_eq!(decoded, [bus]);
633
634        let parts = [
635            DeviceInfo {
636                bus: 0,
637                addr: 0x55,
638                name: "BQ27220",
639            },
640            DeviceInfo {
641                bus: 0,
642                addr: 0x6B,
643                name: "",
644            },
645        ];
646        let mut len = 0;
647        for part in &parts {
648            len += part.encode(&mut table[len..]).unwrap();
649        }
650        let decoded: Vec<DeviceInfo<'_>> =
651            devices(&table[..len]).collect::<Result<_, _>>().unwrap();
652        assert_eq!(decoded, parts);
653    }
654
655    #[test]
656    fn malformed_tables_are_refused() {
657        // Too short for the fixed fields.
658        assert_eq!(BusInfo::decode(&[0, 0x90, 0x01]), Err(I2cError::Parse));
659        assert_eq!(DeviceInfo::decode(&[0]), Err(I2cError::Parse));
660        // A name that is not UTF-8.
661        assert_eq!(
662            BusInfo::decode(&[0, 0x90, 0x01, 0xFF, 0x00, 16, 0xFF]),
663            Err(I2cError::Invalid)
664        );
665        assert_eq!(DeviceInfo::decode(&[0, 0x55, 0xC0]), Err(I2cError::Invalid));
666        // A truncated item prefix.
667        assert_eq!(buses(&[9, 0, 0]).next(), Some(Err(I2cError::Parse)));
668        // A name past what this crate encodes.
669        let long = [b'x'; NAME_MAX_LEN + 1];
670        let bus = BusInfo {
671            bus: 0,
672            speed_khz: 100,
673            max_data: 32,
674            max_ops: 4,
675            name: core::str::from_utf8(&long).unwrap(),
676        };
677        assert_eq!(bus.encode(&mut [0u8; 128]), Err(ItemError::BadLength));
678    }
679}