aboutsummaryrefslogtreecommitdiff
path: root/src/sw/hash_tester.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sw/hash_tester.c')
-rw-r--r--src/sw/hash_tester.c89
1 files changed, 64 insertions, 25 deletions
diff --git a/src/sw/hash_tester.c b/src/sw/hash_tester.c
index d02db41..f202a03 100644
--- a/src/sw/hash_tester.c
+++ b/src/sw/hash_tester.c
@@ -63,15 +63,16 @@
#define EOC 0xaa
#define READ_CMD 0x10
#define WRITE_CMD 0x11
+#define RESET_CMD 0x01
/* response codes */
#define SOR 0xaa
#define EOR 0x55
-#define UNKNOWN 0xfe
-#define ERROR 0xfd
#define READ_OK 0x7f
#define WRITE_OK 0x7e
#define RESET_OK 0x7d
+#define UNKNOWN 0xfe
+#define ERROR 0xfd
/* addresses and codes common to all hash cores */
#define ADDR_NAME0 0x00
@@ -253,26 +254,16 @@ int i2c_write(uint8_t *buf, int len)
return 0;
}
-int i2c_read(uint8_t *buf, int len)
+int i2c_read(uint8_t *b)
{
- int i;
-
- if (debug)
- printf("read [");
-
- for (i = 0; i < len; ++i) {
- if (read(i2cfd, &buf[i], 1) != 1) {
- fprintf(stderr, "i2c read failed on byte %d: ", i);
- perror("");
- return 1;
- }
- if (debug)
- printf(" %02x", buf[i]);
+ /* read() on the i2c device only returns one byte at a time,
+ * and tc_get_resp() needs to parse the response one byte at a time
+ */
+ if (read(i2cfd, b, 1) != 1) {
+ perror("i2c read failed");
+ return 1;
}
- if (debug)
- printf(" ]\n");
-
return 0;
}
@@ -307,12 +298,58 @@ int tc_send_read_cmd(uint8_t addr0, uint8_t addr1)
return i2c_write(buf, sizeof(buf));
}
-int tc_get_resp(uint8_t *expected, int len)
+int tc_get_resp(uint8_t *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; ++i) {
+ if (i2c_read(&buf[i]) != 0)
+ return 1;
+ if ((i == 0) && (buf[i] != SOR)) {
+ /* we've gotten out of sync, and there's probably nothing we can do */
+ fprintf(stderr, "response byte 0: expected 0x%02x (SOR), got 0x%02x\n",
+ SOR, buf[0]);
+ return 1;
+ }
+ else if (i == 1) { /* response code */
+ switch (buf[i]) {
+ case READ_OK:
+ len = 9;
+ break;
+ case WRITE_OK:
+ len = 5;
+ break;
+ case RESET_OK:
+ len = 3;
+ break;
+ case ERROR:
+ case UNKNOWN:
+ len = 4;
+ break;
+ default:
+ /* we've gotten out of sync, and there's probably nothing we can do */
+ fprintf(stderr, "unknown response code 0x%02x\n", buf[i]);
+ return 1;
+ }
+ }
+ }
+
+ if (debug) {
+ printf("read [");
+ for (i = 0; i < len; ++i)
+ printf(" %02x", buf[i]);
+ printf(" ]\n");
+ }
+
+ return 0;
+}
+
+int tc_get_expected(uint8_t *expected, int len)
{
uint8_t buf[9];
int i;
- if (i2c_read(buf, len) != 0)
+ if (tc_get_resp(buf, sizeof(buf)) != 0)
return 1;
for (i = 0; i < len; ++i) {
@@ -336,7 +373,7 @@ int tc_get_write_resp(uint8_t addr0, uint8_t addr1)
expected[3] = addr1;
expected[4] = EOR;
- return tc_get_resp(expected, sizeof(expected));
+ return tc_get_expected(expected, sizeof(expected));
}
int tc_get_read_resp(uint8_t addr0, uint8_t addr1, uint32_t data)
@@ -353,7 +390,7 @@ int tc_get_read_resp(uint8_t addr0, uint8_t addr1, uint32_t data)
expected[7] = data & 0xff;
expected[8] = EOR;
- return tc_get_resp(expected, sizeof(expected));
+ return tc_get_expected(expected, sizeof(expected));
}
int tc_write(uint8_t addr0, uint8_t addr1, uint32_t data)
@@ -385,7 +422,9 @@ int tc_wait(uint8_t addr0, uint8_t status)
do {
if (tc_send_read_cmd(addr0, ADDR_STATUS) != 0)
return 1;
- if (i2c_read(buf, 9) != 0)
+ if (tc_get_resp(buf, 9) != 0)
+ return 1;
+ if (buf[1] != READ_OK)
return 1;
} while ((buf[7] & status) != status);
@@ -869,7 +908,7 @@ int main(int argc, char *argv[])
int addr = I2C_addr;
int i, j, opt;
- while ((opt = getopt(argc, argv, "di:a:")) != -1) {
+ while ((opt = getopt(argc, argv, "h?di:a:")) != -1) {
switch (opt) {
case 'h':
case '?':