nmhw21: fct_atecc: add factory test for ATECC chip
BugzID: 61904
This commit is contained in:
parent
ce70a04c33
commit
a583bb6eea
|
|
@ -10,4 +10,4 @@ ifeq ($(CONFIG_SKIP_LOWLEVEL_INIT),)
|
|||
obj-y := mux.o
|
||||
endif
|
||||
|
||||
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o ../common/da9063.o fileaccess.o sja1105.o ui.o um.o
|
||||
obj-y += board.o ../common/bdparser.o ../common/board_descriptor.o ../common/da9063.o fileaccess.o sja1105.o ui.o um.o fct_atecc.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* fct_atecc.c
|
||||
*
|
||||
* Microchip ATECC608 test
|
||||
*
|
||||
* Copyright (C) 2018-2020 NetModule AG - http://www.netmodule.com/
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#include "fct_atecc.h"
|
||||
|
||||
|
||||
#define REG_SLEEP 0x01
|
||||
#define REG_COMMAND 0x03
|
||||
|
||||
#define WAKE_DELAY_US 1500
|
||||
|
||||
#define RNG_MAX_EXEC_TIME_MS 23
|
||||
#define READ_MAX_EXEC_TIME_MS 1 /* 4 bytes read, 32 bytes = ? */
|
||||
|
||||
|
||||
static void wake_chip(void)
|
||||
{
|
||||
int j;
|
||||
|
||||
|
||||
i2c_set_bus_speed(50000);
|
||||
|
||||
/* wake up sequence, same as i2c probe on command line (proven to work) */
|
||||
for (j = 0; j < 128; j++) {
|
||||
i2c_probe(j);
|
||||
}
|
||||
|
||||
udelay(WAKE_DELAY_US+1000);
|
||||
|
||||
i2c_set_bus_speed(400000);
|
||||
}
|
||||
|
||||
static int put_in_sleep(void)
|
||||
{
|
||||
uchar temp[1];
|
||||
int ret;
|
||||
|
||||
/* put back into sleep mode */
|
||||
ret = i2c_write(CONFIG_ATECC_I2C_ADDR, REG_SLEEP, 1, temp, 0);
|
||||
if (ret != 0) {
|
||||
puts("can't put device in sleep mode\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_rng(void)
|
||||
{
|
||||
uchar rng_cmd[7] = { 7, 0x1B, 0x00, 0x00, 0x00, 0x24, 0xCD };
|
||||
uchar temp[32+3];
|
||||
int ret;
|
||||
|
||||
|
||||
ret = i2c_write(CONFIG_ATECC_I2C_ADDR, REG_COMMAND, 1, rng_cmd, 7);
|
||||
if (ret != 0) {
|
||||
puts("error sending command\n");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
mdelay(RNG_MAX_EXEC_TIME_MS+10);
|
||||
|
||||
/*
|
||||
* Get random number
|
||||
* will be ff ff 00 00 ff ff 00 00 .. if chip is unlocked
|
||||
*/
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
ret = i2c_read(CONFIG_ATECC_I2C_ADDR, 0x00, 0, temp, 32+3);
|
||||
if (ret != 0) {
|
||||
puts("error reading RNG response\n");
|
||||
goto abort;
|
||||
}
|
||||
#if 0
|
||||
for (i=0; i<32+3; i++) {
|
||||
printf("%02x ", temp[i]);
|
||||
}
|
||||
puts("\n");
|
||||
#endif
|
||||
if (temp[0] != 0x23 || temp[33] != 0x41 || temp[34] != 0x1a) {
|
||||
puts("invalid data returned\n");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (temp[33] == 0x41 && temp[34] == 0x1a) {
|
||||
puts("RNG: ok (chip unlocked)\n");
|
||||
}
|
||||
else {
|
||||
puts("RNG: ok (chip locked)\n");
|
||||
}
|
||||
|
||||
abort:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_serial_num(void)
|
||||
{
|
||||
uchar read_cfg32_cmd[7] = { 7, 0x02, 0x80, 0x00, 0x00, 0x09, 0xAD };
|
||||
uchar temp[32+3];
|
||||
uchar sn[9];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
||||
/*
|
||||
* Read beginning of config zone, get S/N
|
||||
* S/N = 0..3, 8..12
|
||||
*/
|
||||
ret = i2c_write(CONFIG_ATECC_I2C_ADDR, REG_COMMAND, 1, read_cfg32_cmd, 7);
|
||||
if (ret != 0) {
|
||||
puts("error sending READ command\n");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
mdelay(READ_MAX_EXEC_TIME_MS+10);
|
||||
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
ret = i2c_read(CONFIG_ATECC_I2C_ADDR, 0x00, 0, temp, 32+3);
|
||||
if (ret != 0) {
|
||||
puts("error reading response\n");
|
||||
goto abort;
|
||||
}
|
||||
#if 0
|
||||
for (i=0; i<32+3; i++) {
|
||||
printf("%02x ", temp[i]);
|
||||
}
|
||||
puts("\n");
|
||||
#endif
|
||||
memcpy(&sn[0], &temp[1], 4);
|
||||
memcpy(&sn[4], &temp[9], 5);
|
||||
puts("S/N: ");
|
||||
for (i=0; i<9; i++) {
|
||||
printf("%02x ", sn[i]);
|
||||
}
|
||||
puts("\n");
|
||||
|
||||
abort:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int do_atecc_test(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
i2c_set_bus_num(CONFIG_ATECC_I2C_BUS);
|
||||
|
||||
wake_chip();
|
||||
|
||||
ret = test_rng();
|
||||
if (ret != 0) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
ret = test_serial_num();
|
||||
if (ret != 0) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
ret = put_in_sleep();
|
||||
if (ret != 0) {
|
||||
goto abort;
|
||||
}
|
||||
|
||||
i2c_set_bus_speed(100000);
|
||||
|
||||
puts("test passed\n");
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
i2c_set_bus_speed(100000);
|
||||
|
||||
puts("test failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_fct_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
goto cmd_usage;
|
||||
|
||||
do_atecc_test();
|
||||
|
||||
return 0;
|
||||
|
||||
cmd_usage:
|
||||
return cmd_usage(cmdtp);
|
||||
}
|
||||
|
||||
|
||||
U_BOOT_CMD(
|
||||
fct, 2, 1, do_fct_test,
|
||||
"factory test subsystem\n",
|
||||
"atecc - tests ATECC chip"
|
||||
);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* fct_atecc.c
|
||||
*
|
||||
* Microchip ATECC608 test
|
||||
*
|
||||
* Copyright (C) 2018-2020 NetModule AG - http://www.netmodule.com/
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef FCT_ATECC_H
|
||||
#define FCT_ATECC_H
|
||||
|
||||
|
||||
#define CONFIG_ATECC_I2C_BUS 0
|
||||
#define CONFIG_ATECC_I2C_ADDR 0x60
|
||||
|
||||
|
||||
#endif /* FCT_ATECC_H */
|
||||
Loading…
Reference in New Issue