WARNING: AS THE DEVICE CAN BE CONFIGURED ONLY ONCE, PLEASE BE WARNED THAT YOU MIGHT EASILY BRICK THE CHIP! USE AT YOUR OWN RISK!
Please make sure to use proper circuit for ATECC608A with pullups and decoupling capacitors when hooked to a MCU. A Raspberry Pi might also work without external components just using internal pullups.
Besides SPI only ATECC608A, there are different versions available. As a hobbyist the sourcing might be difficult and it is not always clear which device you will get (e.g. from China vendors). Overall default is 0xC0
programmed code which will translate to 0x60
. Besides that, you might have gotten an ATECC508A chip listening to the same addresses but with less features. The chips are not marked so you have to trust the vendor. It is somewhat confusing that the I2C address is being read from a configuration byte. Cryptoauthlib reads embedded configuration blobs during initialization. So when there is 0xC0
in the configuration byte 16, it expects the ATECC608A at 0x60. This needs to be changed when you want to interact with a device that has a different I2C address. Then there are also ATECC608B which might introduce more changes. The following list is not complete:
Device | Default 7-bit I2C Address | 8-bit Programmed I2C Address Value |
---|---|---|
ATECC608A-TNGTLS | 0x35 | 0x6A |
ATECC608A-TFLXTLS | 0x36 | x6C |
ATECC608A-MAHDA | 0x60 | 0xC0 |
The following procedure can be used to personalize an ATECC608A for personal experiments with a sample config. This is now my goto procedure for testing purposes.
# ubuntu 20.04
apt update
apt install -y i2c-tools python3-venv python3-pip build-essential cmake git libusbhid-common libusb-1.0-0-dev libhidapi-dev
mkdir ~/git
cd ~/git
git clone https://github.com/MicrochipTech/cryptoauthtools.git
cd cryptauthrools/python/examples
python3 -m venv venv
source venv/bin/activate
pip3 install cryptoauthlib==20190517 --no-cache-dir
pip3 install -r requirements.txt
# needed as i use a pc with only one i2c bus:
cat > config.patch <<"PATCH"
git diff config.py
diff --git a/python/examples/config.py b/python/examples/config.py
index 9579cf4..6d13f37 100644
--- a/python/examples/config.py
+++ b/python/examples/config.py
@@ -79,6 +79,7 @@ def configure_device(iface='hid', device='ecc', i2c_addr=None, keygen=True, **kw
icfg = getattr(cfg.cfg, 'atca{}'.format(iface))
setattr(icfg, k, int(v, 16))
+ cfg.cfg.atcai2c.bus = 0
# Basic Raspberry Pi I2C check
if 'i2c' == iface and check_if_rpi():
cfg.cfg.atcai2c.bus = 1
PATCH
git apply config.patch
i2cdetect -y 0
# this should yield an i2c device at 0x60 - the default before personalization
# THE FOLLOWING COMMAND IS DANGEROUS AND CAN ONLY BE EXECUTED ONCE!
# I WANT NO COMPLAINTS. ALL AT YOUR OWN RISKS. I BURNED SOME ATECC608 DURING EXPERIMENTING!
# MOST LIKELY YOU CAN STILL USE THE CHIP BUT WITH A NON-DEFAULT I2C ADDRESS ONLY SOME TOOLS/LIBS WORK!
# FOR NON-COMMERCIAL TINKERING, ALL ATECC608 WE CAN SOURCE CAN BE DIFFERENT! THE CHIP IS NOT MARKED!
python3 config.py -i i2c --i2c 0xC0 # this will set the i2c address to 0x60 even when using other ATECC608A chip
Using atecc-util one can easily interact with ATECC608A devices attached to I2C bus on Linux. Even when it is configured to use a different I2C address.
# ubuntu 20.04
apt install -y python3-venv python3-pip build-essential cmake git libusbhid-common libusb-1.0-0-dev libhidapi-dev
mkdir ~/git
cd ~/git
git clone https://github.com/wirenboard/atecc-util.git
cd atecc-util
git submodule init
git submodule update
# patch the configuration byte to use a different i2c address
cat > atecc.patch <<"PATCH"
diff --git a/config.h b/config.h
index 6fa7f00..5d1e24e 100644
--- a/config.h
+++ b/config.h
@@ -1,6 +1,6 @@
#pragma once
#define DEFAULT_I2C_BUS 9
-#define DEFAULT_I2C_SLAVE 0xC0
+#define DEFAULT_I2C_SLAVE 0x6A
#define MAX_CMDS 32
PATCH
git apply atecc.patch
make
dpkg-buildpackage
dpkg -i atecc-util*
Use i2cdetect -y 0
to scan bus 0
in order to detect the used i2c address of your device.
You should use the atecc
command first to grab some valuable information about your device for any troubleshooting needs. This also makes sure that you can interact with the device.
modprobe i2c_dev # make sure the i2c bus gets enumerated in /dev/i2c-*
# -b 0 is the first bus. on newer raspberry pi you need -b 1, on a pc you could have many!
# get the serial of the device
./atecc -b 0 -c "serial" > serial.txt
# save configuration bytes and decoded information to file
touch config.dump
./atecc -b 0 -c "dump-config config.dump"
# see whether device is already locked
./atecc -b 0 -c "config-is-locked" > lock.status
Then the following command can be executed ONCE in order to permanent change the address for i2c A SINGLE TIME:
./atecc -b 0 -c "extra-set 85 0xC0"
# power down/up i2c device; i2c is not hotplugable!
However it seems that not all ATECC608A allow to have the I2C reset once the configuration is locked. Without locking the configuration, you could not interact with the device and execute cryptographic functions.
Connect device according to the following schematic (header is the same on Pi Zero):
# raspbian buster lite
sudo apt update
sudo apt install -y i2c-tools python3-venv python3-pip build-essential cmake git libusbhid-common libusb-1.0-0-dev libhidapi-dev
cd
mkdir git
cd git
git clone https://github.com/adafruit/Adafruit_CircuitPython_ATECC.git
cd Adafruit_CircuitPython_ATECC/
python3 -m venv venv
source venv/bin/activate
pip3 install wheel
pip3 install -r requirements.txt
i2cdetect -y 1
# 0 1 2 3 4 5 6 7 8 9 a b c d e f
#00: -- -- -- -- -- -- -- -- -- -- -- -- --
#10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#30: -- -- -- -- -- 35 -- -- -- -- -- -- -- -- -- --
#40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
#70: -- -- -- -- -- -- -- --
pip3 freeze
#Adafruit-Blinka==6.3.0
#adafruit-circuitpython-binascii==1.2.5
#adafruit-circuitpython-busdevice==5.0.6
#Adafruit-PlatformDetect==3.2.0
#Adafruit-PureIO==1.1.8
#pkg-resources==0.0.0
#pyftdi==0.52.9
#pyserial==3.5
#pyusb==1.1.1
#rpi-ws281x==4.2.5
#RPi.GPIO==0.7.0
#sysv-ipc==1.1.0
python3 setup.py bdist_wheel
# patch the i2c address if yours is different to 0x60 (in this case 0x35)
cat > atecc.patch <<"PATCH"
--- atecc.patch 2021-03-04 21:21:07.229852937 +0000
+++ atecc.patch2 2021-03-04 21:20:52.339761410 +0000
@@ -3,13 +3,13 @@
--- a/adafruit_atecc/adafruit_atecc.py
+++ b/adafruit_atecc/adafruit_atecc.py
@@ -59,7 +59,7 @@ def _convert_i2c_addr_to_atecc_addr(i2c_addr=0x60):
-
-
+
+
# Device Address
-_I2C_ADDR = 0x60
+_I2C_ADDR = 0x35
_REG_ATECC_ADDR = _convert_i2c_addr_to_atecc_addr(i2c_addr=_I2C_ADDR)
-
+
_REG_ATECC_DEVICE_ADDR = _REG_ATECC_ADDR >> 1
diff --git a/examples/atecc_simpletest.py b/examples/atecc_simpletest.py
index 088f48e..403e179 100644
@@ -17,10 +17,10 @@
+++ b/examples/atecc_simpletest.py
@@ -9,7 +9,7 @@ from adafruit_atecc.adafruit_atecc import ATECC, _WAKE_CLK_FREQ
i2c = busio.I2C(board.SCL, board.SDA, frequency=_WAKE_CLK_FREQ)
-
+
# Initialize a new atecc object
-atecc = ATECC(i2c)
+atecc = ATECC(i2c, address=0x35, debug=False)
-
+
print("ATECC Serial: ", atecc.serial_number)
-
+
PATCH
# force reinstall in case original wheel already installed during testing
pip3 install --upgrade --force-reinstall dist/adafruit_circuitpython_atecc-1.2.6-py3-none-any.whl
python3 examples/atecc_simpletest.py
#ATECC Serial: 0123E*************
#Random Value: 525
#ATECC Counter #1 Value: bytearray(b'\t\x00\x00\x00')
#Appending to the digest...
#Appending to the digest...
#SHA Digest: bytearray(b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06')
Hi, Thanks for doing this! Happy to see this worked for you :)
If time permits, kindly create a post with photos of your setup and how you connected the ATECC608A breakout board to Raspberry pi.