Skip to main content

atecc608b/command/
info.rs

1// Copyright (c) 2026 Tuloup Simon
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16//! `Info` command.
17//!
18//! The `Info` command (opcode `0x30`) returns 4 bytes of status. Several
19//! modes are available, the most commonly used one being `Revision` which
20//! returns the silicon revision code. For an ATECC608B in M0 clock divider
21//! mode this is `00 00 60 02`, and `00 00 60 03` for M1.
22//!
23//! Reference: `CryptoAuthLib` `lib/calib/calib_info.c`.
24
25use crate::driver::AteccChannel;
26use crate::error::AteccError;
27use crate::hal::AteccHal;
28use crate::opcodes::{EXEC_TIME_INFO_MS, OP_INFO};
29
30/// `Info` mode bytes (Param1).
31///
32/// Only the `Revision` mode is implemented because it is the only one
33/// this project consumes. The chip supports four other modes (`KeyValid`,
34/// `State`, `Gpio`, `VolatileKeyPermission`); they can be added if a
35/// concrete need arises.
36///
37/// Source: `CryptoAuthLib` `lib/calib/calib_command.h`, `INFO_MODE_*` constants.
38#[repr(u8)]
39#[derive(Debug, Clone, Copy)]
40pub(crate) enum InfoMode
41{
42    /// Return the silicon revision (4 bytes).
43    Revision = 0x00,
44}
45
46impl<H> AteccChannel<'_, H>
47where
48    H: AteccHal,
49{
50    /// Read the chip's revision bytes.
51    ///
52    /// Returns the 4-byte revision code. The first two bytes are reserved
53    /// and always zero. The third byte is the device family (`0x60` for
54    /// ATECC608B). The fourth byte distinguishes the clock divider variant
55    /// (`0x02` for M0, `0x03` for M1, `0x04` for M2).
56    ///
57    /// # Errors
58    /// See [`AteccChannel::execute_command`].
59    pub async fn info_revision(&mut self) -> Result<[u8; 4], AteccError<H::Error>>
60    {
61        let mut response_buf = [0u8; 7];
62        let payload = self
63            .execute_command
64            (
65                OP_INFO,
66                InfoMode::Revision as u8,
67                0x0000,
68                &[],
69                EXEC_TIME_INFO_MS,
70                &mut response_buf,
71            )
72            .await?;
73
74        if payload.len() != 4
75        {
76            return Err(AteccError::MalformedResponse);
77        }
78
79        let mut out = [0u8; 4];
80        out.copy_from_slice(payload);
81        Ok(out)
82    }
83}